hs2d
hs2d

Reputation: 6199

C# Kill all threads

I have an application that invokes my DLL with InvokeMember() like so:

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

}

My DLL then creates new a thread and starts processing. In my DLL, I the create new thread like this:

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

The goal is to periodically check the folder. The problem is that when I close the application that invokes my DLL, the process is not closed. Is there a way to close all the threads?

NB: I can’t modify the application, I can only modify my DLL.

Upvotes: 6

Views: 6984

Answers (4)

Surjit Samra
Surjit Samra

Reputation: 4662

How about implementing Safe Cancellation from 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();
  }
}

Test

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

Upvotes: 1

Petr Behenský
Petr Behenský

Reputation: 620

You can use background thread mentioned above or timer:

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

Don't forget to Dispose it.

Upvotes: 0

Bas
Bas

Reputation: 27115

Did you try using a System.IO.FileSystemWatcher? this throws events when something changes in a folder. It looks like this will simplify your solution.

Upvotes: 6

GvS
GvS

Reputation: 52511

Set the IsBackground property of the thread to true. This will kill the thread when your app finishes.

Also: Why don't you use one timer (or just one thread), that wakes and eximines the data. That should be more resource friendly.

Upvotes: 8

Related Questions