我在打电话 ChannelServer.ListeningThread.Abort 在以下线程中,似乎没有任何事情发生。我想更加具体,但我再也想不到。似乎没有 ThreadAbortException 这是抛出的,无论阻止侦听器如何,都应抛出这个例外(它可以完美地适用于封锁的线程)。

重要编辑: :与 ManualResetEvent.WaitOne 代替 AcceptSocket, 正如Lyrik建议进行测试的那样,它可以很好地工作。怎么会 AcceptSocket 阻止 ThreadAbortException?

关联: :这个论坛线程似乎讨论了同一问题,尽管我无法弄清楚它: 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();
有帮助吗?

解决方案 2

这起作用了,但它令人难以置信的草率和浪费。谁能将我指出一种抛出“ 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();

其他提示

我不确定您为什么会遇到这个错误,但这是一个有效的简单示例:

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();

因此,它对我有用...我以为您已经踏上了调试器,并且您的收获声明中的断开点没有受到打击,这是正确的吗?

注意:打电话是不好的做法 Abort, ,相反,您应该致电 Interrupt 并处理 ThreadInterruptedException...更安全。

这是一个简单的 AcceptSocket2 扩展方法(对不起,对名称缺乏想象力...)。它完全像原始 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;
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top