Starting multiple threads and keeping track of the

2020-02-08 06:16发布

I would like to start x number of threads from my .NET application, and I would like to keep track of them as I will need to terminate them manually or when my application closes my application later on.

Example ==> Start Thread Alpha, Start Thread Beta .. then at any point in my application I should be able to say Terminate Thread Beta ..

What is the best way to keep track of opened threads in .NET and what do I need to know ( an id ? ) about a thread to terminate it ? Sample code, tutorial would be helpful.

7条回答
We Are One
2楼-- · 2020-02-08 06:40

As you start each thread, put it's ManagedThreadId into a Dictionary as the key and the thread instance as the value. Use a callback from each thread to return its ManagedThreadId, which you can use to remove the thread from the Dictionary when it terminates. You can also walk the Dictionary to abort threads if needed. Make the threads background threads so that they terminate if your app terminates unexpectedly.

You can use a separate callback to signal threads to continue or halt, which reflects a flag set by your UI, for a graceful exit. You should also trap the ThreadAbortException in your threads so that you can do any cleanup if you have to abort threads instead.

查看更多
干净又极端
3楼-- · 2020-02-08 06:52

Wow, there are so many answers..

  1. You can simply use an array to hold the threads, this will only work if the access to the array will be sequantial, but if you'll have another thread accessing this array, you will need to synchronize access
  2. You can use the thread pool, but the thread pool is very limited and can only hold fixed amount of threads.
  3. As mentioned above, you can create you own thread pool, which in .NET v4 becomes much easier with the introduction of safe collections.
  4. you can manage them by holding a list of mutex object which will determine when those threads should finish, the threads will query the mutex each time they run before doing anything else, and if its set, terminate, you can manage the mutes from anywhere, and since mutex are by defenition thread-safe, its fairly easy..

i can think of another 10 ways, but those seems to work. let me know if they dont fit your needs.

查看更多
贼婆χ
4楼-- · 2020-02-08 06:52

Depends on how sophisticated you need it to be. You could implement your own type of ThreadPool with helper methods etc. However, I think its as simple as just maintaining a list/array and adding/removing the threads to/from the collection accordingly.

You could also use a Dictionary collection and use your own type of particular key to retrieve them i.e. Guids/strings.

查看更多
爷、活的狠高调
5楼-- · 2020-02-08 06:54

You could save yourself the donkey work and use this Smart Thread Pool. It provides a unit of work system which allows you to query each thread's status at any point, and terminate them.

If that is too much bother, then as mentioned anIDictionary<string,Thread> is probably the simplest solution. Or even simpler is give each of your thread a name, and use an IList<Thread>:

public class MyThreadPool
{
    private IList<Thread> _threads;
    private readonly int MAX_THREADS = 25;

    public MyThreadPool()
    {
        _threads = new List<Thread>();
    }

    public void LaunchThreads()
    {
        for (int i = 0; i < MAX_THREADS;i++)
        {
            Thread thread = new Thread(ThreadEntry);
            thread.IsBackground = true;
            thread.Name = string.Format("MyThread{0}",i);

            _threads.Add(thread);
            thread.Start();
        }
    }

    public void KillThread(int index)
    {
        string id = string.Format("MyThread{0}",index);
        foreach (Thread thread in _threads)
        {
            if (thread.Name == id)
                thread.Abort();
        }
    }

    void ThreadEntry()
    {

    }
}

You can of course get a lot more involved and complicated with it. If killing your threads isn't time sensitive (for example if you don't need to kill a thread in 3 seconds in a UI) then a Thread.Join() is a better practice.

And if you haven't already read it, then Jon Skeet has this good discussion and solution for the "don't use abort" advice that is common on SO.

查看更多
放荡不羁爱自由
6楼-- · 2020-02-08 06:55

After creating your thread, you can set it's Name property. Assuming you store it in some collection you can access it conveniently via LINQ in order to retrieve (and abort) it:

var myThread = (select thread from threads where thread.Name equals "myThread").FirstOrDefault();
if(myThread != null)
    myThread.Abort();
查看更多
贼婆χ
7楼-- · 2020-02-08 06:56

You can create a Dictionary of threads and assign them id's, like:

Dictionary<string, Thread> threads = new Dictionary<string, Thread>();
for(int i = 0 ;i < numOfThreads;i++)
{
    Thread thread = new Thread(new ThreadStart(MethodToExe));
    thread.Name = threadName; //Any name you want to assign
    thread.Start(); //If you wish to start them straight away and call MethodToExe
    threads.Add(id, thread);
}

If you don't want to save threads against an Id you can use a list and later on just enumerate it to kill threads.

And when you wish to terminate them, you can abort them. Better have some condition in your MethodToExe that allows that method to leave allowing the thread to terminate gracefully. Something like:

void MethodToExe()
{
   while(_isRunning)
   {
      //you code here//
      if(!_isRunning)
      {
          break;
      }
      //you code here//
   }
}

To abort you can enumerate the dictionary and call Thread.Abort(). Be ready to catch ThreadAbortException

查看更多
登录 后发表回答