如何在C#中关闭包含阻塞方法的线程

时间:2013-02-08 19:04:37

标签: c# multithreading methods blocking terminate

我创建了一个线程来处理我的代码中的阻塞方法。这样,除了运行阻塞方法之外,我的代码可以做其他事情。

问题:如何正确终止线程?我是否必须取消阻止阻塞方法,然后终止该线程。或者我可以直接终止线程而不用担心任何丑陋的崩溃?

3 个答案:

答案 0 :(得分:0)

致电yourthread.Abort()。它不像过去那样,当资源和锁没有被释放时,这会导致你破坏所有东西,现在这会导致一个很好的例外,可以通过正常的方式处理......

http://msdn.microsoft.com/en-us/library/system.threading.thread.abort.aspx

当我说“正常方式”时,似乎线程中止异常自动重新提升(非常好的技巧)

http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx

但这并不能阻止你成为一个冲洗,并在捕获区域开始另一件大事......

答案 1 :(得分:0)

你有一些选择。如果您不关心在应用程序停机时操作是否完成,您可能最好通过QueueUserWorkItem使用ThreadPool线程或(如Servy在评论中建议的那样)设置线程的IsBackground属性为true,这将允许进程在没有线程退出的情况下退出。

如果你关心完成的操作和/或需要在关机时运行的清理逻辑,你可能真的不想使用Thread.Abort,至少不是你的goto策略。我使用的是类似的东西:

public abstract class DisposableThread : IDisposable
{
    private ManualResetEvent exiting = new ManualResetEvent(false);
    private Thread theThread;
    private  TimeSpan abortTimeout;

    public DisposableThread():
        this(TimeSpan.FromMilliseconds(100))
    {
    }

    public DisposableThread(TimeSpan abortTimeout)
    {
        this.abortTimeout = abortTimeout;
        theThread = new Thread((_) => ThreadProc());
    }

    protected virtual void ThreadProc()
    {
        while(!exiting.WaitOne(0))
        {
            WorkUnit(exiting);
        }
        ThreadCleanup();
    }

    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        exiting.Set();
        if (!theThread.Join(abortTimeout))
        {
            // logme -- the thread didn't shutdown gracefully
            theThread.Abort();
            while (!theThread.Join(1000))
            {
                // logme -- the thread is doing something dumb in an exception handler
            }
        }
        exiting.Dispose();
    }

    // WorkUnit should return as quickly as safe if the exiting handle is set
    // If it doesn't the thread will be aborted if it takes longer than abortTimeout
    protected abstract void WorkUnit(WaitHandle exiting);

    // override if you need to cleanup on exit
    protected virtual void ThreadCleanup() { }
}

这使您的线程有机会优雅退出,只有在正常退出失败时才会中止。

答案 2 :(得分:0)

行, 找到了我的答案。我必须声明线程,以便可以对它们进行引用。然后,我首先结束嵌套线程(其中包含HandleClientComm()),然后关闭TCP_Client(如果不为null)和TCP_Listener。然后我结束了ListenThread()。此外,必须实现此处提到的TCP_Listener.Pending()方法Proper way to stop TcpListener

相关问题