停止线程后,我可以用变量取消listen操作吗?

时间:2017-03-29 08:57:15

标签: c# sockets asyncsocket

我使用以下方法侦听线程中的端口。在等待WaitOne方法时,我停止线程(我正在做IsCancellationRequested为真),我无法关闭listener对象。当我想听同一个端口时,我收到一个错误。

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

我不想检查线程是否已使用单独的线程停止并关闭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类是我创建的包含System.Threading.CancellationTokenSource CancellationTokenSource属性的类。

1 个答案:

答案 0 :(得分:1)

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

您可以尝试等待两个手柄。 (未测试的)

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

int index = EventWaitHandle.WaitAny(handles);

WaitAny返回whois设置的waithandle的索引。因此,确定你是否想要打破你的一生。

也许像:

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