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

本文关键字:方法 线程 包含阻 何关闭 | 更新日期: 2023-09-27 17:58:18

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

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

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

调用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

但这并不能阻止你成为一个笨蛋,在接球区踢出另一件大事。。。

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

如果您确实关心操作的完成和/或有需要在关闭时运行的清理逻辑,那么您可能并不真的想使用Thread。中止,至少不要作为你的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() { }
}

这给了线程一个优雅退出的机会,并且只有在优雅退出失败时才会中止。

OK,找到了我的答案。我必须声明线程,以便可以对它们进行引用。然后,我首先结束嵌套线程(它有HandleClientComm()),然后关闭TCP_Client(如果不是null)和TCP_Listener。然后我结束ListenThread()。还有TCP_Listener。这里提到的Pending()方法必须实现停止TcpListener的正确方法。