开发者

How to restart a task elegantly?

So I have something like this:

Task.Factory.FromAsync<TcpClient>(tcpListener.BeginAcceptTcpClient, tcpListener.EndAcceptTcpClient, tcpListener).ContinueWith(ConnectionAccepted);

private void Connectio开发者_如何学GonAccepted(Task<TcpClient> tcpClientTask)
{
    TcpClient tcpClient = tcpClientTask.Result;

    // Do something with tcpClient
}

Now I'm wondering, how can I initiate Task.Factory.FromAsync<TcpClient>(...) again at the end of this method? I can't really just copy and paste the line of code because I don't have access to TcpListener and would rather not make it a member variable. Even if I did though, it's such a long line of code it kinda feels like code duplication to me.

Does the Tasks framework provide some sort of mechanism to accomplish this?

Thanks.


As svick suggested, the easiest way would be to make tcpListener in to a field. But if for some reason you can't do that, try this pattern:

void AcceptClient()
{
    // Create tcpListener here.
    AcceptClientImpl(tcpListener);
}

void AcceptClientImpl(TcpListener tcpListener)
{
    Task.Factory.FromAsync<TcpClient>(tcpListener.BeginAcceptTcpClient, tcpListener.EndAcceptTcpClient, tcpListener).ContinueWith(antecedent =>
    {
        ConnectionAccepted(antecedent.Result);

        // Restart task by calling AcceptClientImpl "recursively".
        // Note, this is called from the thread pool. So no stack overflows.
        AcceptClientImpl(tcpListener);
    });
}

void ConnectionAccepted(TcpClient tcpClient)
{
    // Do stuff here.
}


I don't think there is anything in the Framework for restarting Tasks.

But your problem can be trivially solved by putting the tcpListener into a field and putting the line that creates the task into a method, so there won't be any code duplication.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜