2012-01-03 148 views
6

我有調用與InvokeMember()像這樣我的DLL的應用程序:C#殺死所有的線程

Assembly OCA = Assembly.LoadFrom("./Modules/ProcessFiles.dll"); 
Type[] types = OCA.GetTypes(); 
foreach (var type in types) 
{ 
    //MethodInfo[] methods = type.GetMethods(); 
    if (type.Name == "Converter") 
    { 
     var tmpType = type; 
     var obj = Activator.CreateInstance(tmpType); 
     Thread t = new Thread(
      () => 
      tmpType.InvokeMember("Run", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, 
      null)); 
     t.Start(); 
     break; 
    } 

} 

我的DLL,然後創建一個新的線程,並開始處理。在我的DLL,我在創建新的線程是這樣的:

Thread thread = new Thread(
    delegate(){ 
     while(true) 
     { 
      GetFilesInFolder(); 
      Thread.Sleep(120000); 
     } 
    }); 
ne.Start(); 

的目標是定期檢查該文件夾。問題是,當我關閉調用我的DLL的應用程序時,進程未關閉。有沒有辦法關閉所有的線程?

注意:我無法修改應用程序,我只能修改我的DLL。

回答

8

將線程的IsBackground屬性設置爲true。這會在你的應用完成時殺死線程。

另外:爲什麼你不使用一個計時器(或者只是一個線程),它喚醒和取消數據。這應該更加資源友好。

+0

我也嘗試使用計時器,但我不能讓Threading.Timer工作落實安全取消。 – hs2d 2012-01-03 11:42:02

+0

還有Timers.Timer – 2012-01-03 11:44:23

+0

是的,我知道這一切。也許你可以給我一個工作示例如何在我的情況下使用Timer? – hs2d 2012-01-03 11:54:19

6

您是否嘗試過使用System.IO.FileSystemWatcher?這會在文件夾中的某些內容發生變化時拋出事件。看起來這將簡化您的解決方案。

+0

是的,即時使用'FileSystemWatcher'也可以用於新文件和chenges。但它有點更加完善。有些文件尚未準備好處理,我必須將它們留在該文件夾中,稍後再進行檢查。 – hs2d 2012-01-03 11:44:39

0

您可以使用上面或定時器提到的後臺線程:

Timer checkTimer; 
public void StartTimer() 
{ 
    checkTimer = new Timer(s => GetFilesInFolder(), null, 0, 120000); 
} 

不要忘記處置它。

1

如何從here

class RulyCanceler 
{ 
    object _cancelLocker = new object(); 
    bool _cancelRequest; 
    public bool IsCancellationRequested 
    { 
    get { lock (_cancelLocker) return _cancelRequest; } 
    } 

    public void Cancel() { lock (_cancelLocker) _cancelRequest = true; } 

    public void ThrowIfCancellationRequested() 
    { 
    if (IsCancellationRequested) throw new OperationCanceledException(); 
    } 
} 

測試

class Test 
{ 
    static void Main() 
    { 
    var canceler = new RulyCanceler(); 
    new Thread (() => { 
         try { Work (canceler); } 
         catch (OperationCanceledException) 
         { 
          Console.WriteLine ("Canceled!"); 
         } 
         }).Start(); 
    Thread.Sleep (1000); 
    canceler.Cancel();    // Safely cancel worker. 
    } 

    static void Work (RulyCanceler c) 
    { 
    while (true) 
    { 
     c.ThrowIfCancellationRequested(); 
     // ... 
     try  { OtherMethod (c); } 
     finally { /* any required cleanup */ } 
    } 
    } 

    static void OtherMethod (RulyCanceler c) 
    { 
    // Do stuff... 
    c.ThrowIfCancellationRequested(); 
    } 
}