AcceptSocket不尊重Thread.Abort的要求 [英] AcceptSocket does not respect a Thread.Abort request

查看:345
本文介绍了AcceptSocket不尊重Thread.Abort的要求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的理解是,Thread.Abort的应提高对阻塞的线程一个ThreadAbortException,但是这似乎并没有与 TcpListener.AcceptSocket 打交道时是这样。下面是问题的最基本的例子:

My understanding is that Thread.Abort should raise a ThreadAbortException on a blocked thread, however this does not seem to be the case when dealing with TcpListener.AcceptSocket. Here's the most basic illustration of the issue:

class Program
{
    static void Main(string[] args)
    {
        Thread thread = new Thread(Listen);
        thread.Start();
        Thread.Sleep(1000); // give it a second to get going
        Console.WriteLine("Aborting listener thread");
        thread.Abort();
        thread.Join();
        Console.WriteLine("Listener thread finished press <enter> to end app.");
        Console.ReadLine();
    }
    static void Listen()
    {
        try
        {
            Console.WriteLine("Starting to listen");
            TcpListener listener = new TcpListener(IPAddress.Any, 4070);
            listener.Start();
            Socket socket = listener.AcceptSocket();
            Console.WriteLine("Connected!");
            return;
        }
        catch (ThreadAbortException exception)
        {
            Console.WriteLine("Abort requested");
        }
    }
}



Thread.Abort的()呼叫应停止 AcceptSocket 执行 ThreadAbortException 处理程序。 Howerver这不会发生。

The thread.Abort() call should stop the AcceptSocket and execute the ThreadAbortException handler. Howerver this does not happen.

交换了我的倾听ListenAsync AcceptSocket 的包装这就要求 BeginAcceptSocket 而不是:

Swapping out my Listen wrapper of AcceptSocket for ListenAsync which calls BeginAcceptSocket instead:

static void ListenAsync()
    {
        try
        {
            ManualResetEvent clientConnected = new ManualResetEvent(false);

            Console.WriteLine("Starting to listen");
            TcpListener listener = new TcpListener(IPAddress.Any, 4070);
            listener.Start();
            clientConnected.Reset();
            var iasyncResult = listener.BeginAcceptSocket((ar) =>
            {
                Socket socket = listener.EndAcceptSocket(ar);
                Console.WriteLine("Connected!");
                clientConnected.Set();
            }, null);
            clientConnected.WaitOne();

            return;
        }
        catch (ThreadAbortException exception)
        {
            Console.WriteLine("Abort requested");
        }
    }

在出现,它这种情况下正常工作。当线程正在做的WaitOne的ThreadAbortException被捕获。但是,这种被调用BeginAcceptSocket创建线程仍在运行,并且能够接受一个套接字

In this case it "appears" to work fine. The ThreadAbortException is caught while the thread is doing a WaitOne. HOWEVER the thread that was created by the call to BeginAcceptSocket is still running and able to accept a socket (I verified this by opening that port with Telnet)

最后,我说(我通过打开端口的Telnet验证了这一点) Listener.Stop TheadAbortException 处理程序的一部分,和周围的EndAcceptSocket呼叫尝试catch(因为插座布置由停止)

Finally, I added Listener.Stop as part of the TheadAbortException handler, and a try catch around the EndAcceptSocket call (since the socket is disposed by the Stop)

这真的是最好的方法启动和停止监听套接字连接的过程吗?

Is this really the best approach starting and stopping the process of listening for socket connections?

推荐答案

这是 Thread.Abort的不会中止了在听套接字线程的原因是因为线程被阻塞里面(的道德相当值)听()内核调用。在 ThreadAbortException 只能在CLR实际执行CLR提高,并调用在听线程居然把一个非托管的系统调用里面。一旦调用收益和执行的CLR内恢复,线程流产可以继续。

The reason that Thread.Abort doesn't abort a thread that's listening on a socket is because that thread is blocked inside (the moral equivalent of) a listen() kernel call. The ThreadAbortException can only be raised by the CLR when the CLR is actually executing, and during a call to listen thread is actually stuck inside an unmanaged system call. Once the call to listen returns and the execution resumes inside the CLR, the thread abortion can be continued.

我第二个建议不要使用 Thread.Abort的()。如果你决定走这条路,你可以使用一个类似于在你的第二个例子的技术。不过,你最好还是使用不同的方法和简单地调用 Listener.Stop()当你想关闭线程监听器。

I second the advice not to use Thread.Abort(). If you do decide to go that route, you can use a technique similar to the one in your second example. However, you'd be better off using a different method and simply calling Listener.Stop() when you want to shut down the thread listener.

这篇关于AcceptSocket不尊重Thread.Abort的要求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆