如何优雅地重启任务?

时间:2011-10-01 01:53:34

标签: c# task tcpclient task-parallel-library tcplistener

所以我有这样的事情:

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

private void ConnectionAccepted(Task<TcpClient> tcpClientTask)
{
    TcpClient tcpClient = tcpClientTask.Result;

    // Do something with tcpClient
}

现在我想知道,如何在此方法结束时再次启动Task.Factory.FromAsync<TcpClient>(...)?我不能真正复制和粘贴代码行,因为我无权访问TcpListener而宁愿不将其作为成员变量。即使我这样做了,它的代码很长,对我来说有点代码重复。

Tasks框架是否提供了某种机制来实现这一目标?

感谢。

2 个答案:

答案 0 :(得分:2)

正如svick建议的那样,最简单的方法是让tcpListener进入某个字段。但如果由于某种原因你不能这样做,试试这种模式:

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.
}

答案 1 :(得分:1)

我认为框架中没有任何内容可以重新启动Task

但是,通过将tcpListener放入一个字段并将创建任务的行放入方法中,可以轻松解决您的问题,因此不会有任何代码重复。