简体   繁体   English

由于AcceptSocket,Thread.Abort似乎没有抛出ThreadAbortException

[英]Thread.Abort doesn't seem to throw a ThreadAbortException because of AcceptSocket

I am calling ChannelServer.ListeningThread.Abort on the following thread, however nothing seems to happen. 我在下面的线程上调用ChannelServer.ListeningThread.Abort ,但似乎没有任何事情发生。 I would like to be more specific, but I can't think of anything more. 我想更具体一点,但我想不出更多。 There seems to be no ThreadAbortException that is thrown, and this exception should be thrown regardless of the blocking listener (it works perfectly on threads that are blockingly-receiving). 似乎没有抛出ThreadAbortException ,并且无论阻塞侦听器如何都应抛出此异常(它在阻塞接收的线程上完美运行)。

Important EDIT : With a ManualResetEvent.WaitOne instead of AcceptSocket , as Lyrik has suggested for testing, it works perfectly. 重要编辑 :使用ManualResetEvent.WaitOne而不是AcceptSocket ,正如Lyrik建议进行测试一样,它完美无缺。 How come AcceptSocket blocks the ThreadAbortException ? 为什么AcceptSocket阻止ThreadAbortException

LINK : This forum thread seems to discuss the same issue, although I cannot figure anything out of it: http://www.tek-tips.com/viewthread.cfm?qid=319436&page=413 链接 :这个论坛主题似乎讨论了同样的问题,虽然我无法解决任何问题: http//www.tek-tips.com/viewthread.cfm?qid = 319436&page = 413

ChannelServer.ListeningThread = new Thread(new ThreadStart(delegate()
{
    Log.Inform("Waiting for clients on thread {0}.", Thread.CurrentThread.ManagedThreadId);

    while (true)
    {
        try
        {
            new Thread(new ParameterizedThreadStart(ChannelClientHandler.Initialize)).Start(ChannelServer.Listener.AcceptSocket());
        }
        catch (ThreadAbortException)
        {
            Log.Inform("Aborted client listening thread {0}.", Thread.CurrentThread.ManagedThreadId);
            break;
        }
    }
}));
ChannelServer.ListeningThread.Start();

Here a simple AcceptSocket2 extension method (sorry for the lack of imagination regarding the name...). 这里有一个简单的AcceptSocket2扩展方法(对于名称缺乏想象力而感到抱歉......)。 It works exactly as the original AcceptSocket method. 它与原始的AcceptSocket方法完全一样。

using System;
using System.Net.Sockets;
using System.Threading;

/// <summary>
/// Extensions to TcpListener
/// </summary>
public static class TcpListenerExtensions
{
    /// <summary>
    /// Accepts a pending connection request.
    /// </summary>
    /// <param name="tcpListener">The TCP listener.</param>
    /// <returns>
    /// A <see cref="T:System.Net.Sockets.Socket" /> used to send and receive data.
    /// </returns>
    /// <exception cref="T:System.InvalidOperationException">The listener has not been started with a call to <see cref="M:System.Net.Sockets.TcpListener.Start" />.</exception>
    /// <PermissionSet><IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" /><IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /></PermissionSet>
    public static Socket AcceptSocket2(this TcpListener tcpListener)
    {
        Socket socket = null;
        var clientConnected = new ManualResetEvent(false);
        clientConnected.Reset();
        tcpListener.BeginAcceptSocket(delegate(IAsyncResult asyncResult)
        {
            try
            {
                socket = tcpListener.EndAcceptSocket(asyncResult);
            }
            catch (ObjectDisposedException)
            { }
            clientConnected.Set();
        }, null);
        clientConnected.WaitOne();
        return socket;
    }
}

I'm not sure why you're getting that error, but here is a simple example that works: 我不确定你为什么会收到这个错误,但这是一个简单的例子:

ManualResetEvent mrse = new ManualResetEvent(false);
Thread test = new Thread(() =>
    {
        while (true)
        {
            try
            {
                mrse.WaitOne();
            }
            catch (ThreadAbortException)
            {
                Console.WriteLine("No problem here...");
            }
        }
    });

test.IsBackground = true;
test.Start();

Thread.Sleep(1000);
test.Abort();
Console.ReadKey();

So it works for me... I assumed you've stepped through the debugger and your break point inside the catch statement wasn't hit, is that correct? 所以它适用于我...我假设你已经通过调试器并且你的catch语句中的断点没有被击中,这是正确的吗?

Note: it's bad practice to call Abort , instead you should call Interrupt and handle the ThreadInterruptedException ... it's much safer. 注意:调用Abort是不好的做法,而应该调用Interrupt并处理ThreadInterruptedException ...它更安全。

This works, but it's incredibly sloppy and thread-wasting. 这很有效,但它非常邋and和线程浪费。 Could anyone just point me to a way to throw an exception that "AcceptSocket" won't automatically catch? 任何人都可以指出一种方法来抛出“AcceptSocket”不会自动捕获的异常吗?

ChannelServer.ListeningThread = new Thread(new ThreadStart(delegate()
{
    Log.Inform("Waiting for clients on thread {0}.", Thread.CurrentThread.ManagedThreadId);

    while (true)
    {
        try
        {
            ChannelServer.ClientConnected.Reset();
            ChannelServer.Listener.BeginAcceptSocket(new AsyncCallback(ChannelClientHandler.EndAcceptSocket), ChannelServer.Listener);
            ChannelServer.ClientConnected.WaitOne();
        }
        catch (ThreadInterruptedException)
        {
            Log.Inform("Interrupted client listening thread {0}.", Thread.CurrentThread.ManagedThreadId);
            break;
        }
    }
}));
ChannelServer.ListeningThread.Start();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM