Shutting down a multithreaded application

前端 未结 6 1740
谎友^
谎友^ 2020-12-05 09:06

I\'m trying to write a ThreadManager for my C# application. I create several threads:
One thread for my text writer.
One thread that monitors some statistics.
M

相关标签:
6条回答
  • 2020-12-05 09:24

    What if AddThread is called while your Shutdown is running?

    When shutdown finishes, the thread waiting in AddThread will add a new thread to the collection. This could lead to hangs in your app.

    Add a bool flag that you ever only set in Shutdown to protect against this.

    bool shouldGoAway = false;
    public void AddThread(Thread t)
    {
        lock (_sync)
        {
            if( ! shouldGoAway )
                _threads.Add(t);
        }
    }
    
    public void Shutdown()
    {
        lock (_sync)
        {
            shouldGoAway = true;
            foreach (Thread t in _threads)
            {
                t.Abort(); // does this also abort threads that are currently blocking?
            }
        }
    

    Also you should not use static members - there is no reason for that as you have your Singleton instance.

    .Abort() does not abort threads that are blocking in unmanaged space. So if you do that you need to use some other mechanism.

    0 讨论(0)
  • 2020-12-05 09:26

    You want deferred thread cancellation, which basically means that the threads terminate themselves as opposed to a thread manager cancelling threads asynchronously, which is much more ill-defined and dangerous.

    I you wanted to handle thread cancellation more elegantly than immediate termination, you can use signal handlers that are triggered by events outside the thread - by your thread manager perhaps.

    0 讨论(0)
  • 2020-12-05 09:42

    The only specific issue I know about is this one: http://www.bluebytesoftware.com/blog/2007/01/30/MonitorEnterThreadAbortsAndOrphanedLocks.aspx

    But I'd avoid having to resort to a design like this. You could force each of your threads to check some flag regularly that it's time to shut down, and when shutting down, set that flag and wait for all threads to finish (with Join()). It feels a bit more like controlled shutdown that way.

    0 讨论(0)
  • 2020-12-05 09:46

    If you don't care about the worker thread state then you can loop through _thread and abort:

    void DieDieDie()
    {
      foreach (Thread thread in _thread)
        {
          thread.Abort();
          thread.Join(); // if you need to wait for the thread to die
        }
    }
    

    In your case you can probably just abort them all and shutdown as they're just doing calculations. But if you need to wait for a database write operation or need to close an unmanaged resource then you either need to catch the ThreadAbortException or signal the threads to kill themselves gracefully.

    0 讨论(0)
  • 2020-12-05 09:47

    If you set the threads to background threads, they will be killed when the application is shut down.

    myThread.IsBackground = true;
    

    obviously if you need the threads to finish before shutdown, this is not the solution you want.

    0 讨论(0)
  • 2020-12-05 09:47

    Aborting threads is what you do when all else fails. It is a dangerous thing to do which you should only do as a last resort. The correct way to do this is to make your threading logic so that every worker thread responds quickly and correctly when the main thread gives it the command to shut itself down.

    Coincidentally, this is the subject of my blog this week.

    http://blogs.msdn.com/ericlippert/archive/2010/02/22/should-i-specify-a-timeout.aspx

    0 讨论(0)
提交回复
热议问题