2012-01-03 25 views
6

Ho un'applicazione che richiama la mia DLL con InvokeMember() in questo modo:C# Uccidi tutte le discussioni

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; 
    } 

} 

mio DLL crea nuovo un filo e avvia l'elaborazione. Nella mia DLL, creo un nuovo thread come questo:

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

L'obiettivo è controllare periodicamente la cartella. Il problema è che quando chiudo l'applicazione che richiama la mia DLL, il processo non è chiuso. C'è un modo per chiudere tutti i thread?

NB: Non riesco a modificare l'applicazione, posso solo modificare la mia DLL.

risposta

8

Impostare la proprietà IsBackground della discussione su true. Questo ucciderà il thread al termine della tua app.

Inoltre: Perché non si utilizza un timer (o solo un thread), che riattiva ed esalta i dati. Questo dovrebbe essere più favorevole alle risorse.

+0

ho cercato di usare il timer, ma non potevo ottenere il Threading.Timer lavoro. – hs2d

+0

C'è anche Timers.Timer –

+0

Sì, lo so anche io. Forse puoi darmi un esempio funzionante su come usare il Timer nella mia situazione? – hs2d

6

Hai provato a utilizzare un System.IO.FileSystemWatcher? questo genera eventi quando qualcosa cambia in una cartella. Sembra che questo semplificherà la tua soluzione.

+0

Sì, sto usando 'FileSystemWatcher' anche per nuovi file e chenges. Ma è un po 'più compilato. Alcuni file non sono pronti per essere elaborati e devo lasciarli in quella cartella e controllarli più tardi. – hs2d

0

È possibile utilizzare thread in background di cui sopra o un timer:

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

Non dimenticare di smaltire.

1

Come sull'implementazione sicura cancellazione da 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(); 
    } 
} 

prova

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(); 
    } 
}