所以我有这样的事情:
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框架是否提供了某种机制来实现这一目标?
感谢。
答案 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
放入一个字段并将创建任务的行放入方法中,可以轻松解决您的问题,因此不会有任何代码重复。