停止线程后,是否可以用变量取消监听操作?

After stopping the thread, can I cancel the listen operation with a variable?

我用下面的方法在一个线程中监听一个端口。在等待 WaitOne 方法时,我停止了线程(我正在执行 IsCancellationRequested true)并且无法关闭 listener 对象。然后我想听同一个端口就报错了。

我可以将侦听器对象绑定到变​​量吗?如果该变量为假,它将自动关闭。

我不想用单独的线程检查线程是否停止并关闭 listener

public void StartListening(Connection connection)
{
    // There are codes here..
    try
    {
        listener.Bind(localEndPoint);
        listener.Listen(2);

        while (connection.CancellationTokenSource.IsCancellationRequested == false)
        {                
            allDone.Reset();                    
            listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
            allDone.WaitOne(); // While I'm waiting here, I'm making the 'IsCancellationRequested' variable true.
        }

        listener.Close();
    }
    catch (Exception e)
    {
        // There are codes here..
    }

    // There are codes here..
}

注意:Connection class 是我创建的 class,其中包含 System.Threading.CancellationTokenSource CancellationTokenSource 属性.

我不知道 connection 的精确结构,但是...

您可以尝试等待两个句柄。 (未经测试)

var handles = new EventWaitHandle[] 
{ 
    allDone, 
    connection.CancellationTokenSource.Token.WaitHandle 
};

int index = EventWaitHandle.WaitAny(handles);

WaitAny returns waithandle whois 集的索引。因此,请确定您是否要休息一下。


也许蜜蜂是这样的:

public void StartListening(Connection connection)
{
    // There are codes here..
    try
    {
        listener.Bind(localEndPoint);
        listener.Listen(2);

        var handles = new EventWaitHandle[] 
        { 
            allDone, 
            connection.CancellationTokenSource.Token.WaitHandle 
        };

        do
        {                
            allDone.Reset();                    
            listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
        }
        while(EventWaitHandle.WaitAny(handles) == 0);

        listener.Close();
    }
    catch (Exception e)
    {
        // There are codes here..
    }

    // There are codes here..
}

一种取消侦听器的方法。目前无法弥补更好的东西。如果有人有更好的方法...请随意 ;-)

ManualResetEvent _listenerTerminated = new ManualResetEvent(false);

// <snip>

listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

private void AcceptCallback(IAsyncResult ar)
{
    // before calling EndAccept, check an event.
    if(_listenerTerminated.WaitOne(0))
        return;

    var clientSocket = listener.EndAccept(asyncResult);
}

// <snip>

do
{                
    allDone.Reset();                    
    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
while(EventWaitHandle.WaitAny(handles) == 0);

_listenerTerminated.Set();

listener.Close();