【发布时间】:2016-04-23 12:11:09
【问题描述】:
我对@987654323@ 感到困惑,因为我可能仍然不明白它的正确用法。
我有一个简单的WPF-UI 和一个ViewModel-方法来开始监听想要连接的客户端。
当用户点击按钮开始收听时,会执行以下方法:
public void StartListening()
{
_tcpListener.Start(); // TcpListener
IsListening = true; // bool
Task.Factory.StartNew(DoStartListeningAsync, TaskCreationOptions.LongRunning);
}
调用的方法DoStartListeningAsync定义如下
private async Task DoStartListeningAsync()
{
while (IsListening)
{
using (var newClient = await _tcpListener.AcceptTcpClientAsync() /*.WithWaitCancellation(_cts.Token)*/)
{
apiClient = new ApiClient();
if(await apiClient.InitClientAsync()) // <-- here is the problem
{
// ... apiClient is now initialized
}
// ... do more and go back to await _tcpListener.AcceptTcpClientAsync()
}
}
}
ApiClient 类的InitClientAsync 方法定义如下:
public async Task<bool> InitClientAsync()
{
using (var requestStream = await _apiWebRequest.GetRequestStreamAsync())
{
_apiStreamWriter = new StreamWriter(requestStream);
}
// ... do somehing with the _apiStreamWriter
return true;
}
但是,有时InitClientAsync-调用会卡在await _apiWebRequest.GetRequestStreamAsync(),然后将冻结DoStartListeningAsync-方法在// <-- here is the problem 的执行。
如果DoStartListeningAsync 被卡住,将不会处理任何新连接,这会破坏我异步处理多个客户端的整个概念。
【问题讨论】:
-
您可能想阅读 Eric Lippert 的 Asynchronous Programming in C# 5.0 part two: Whence await?:“异步方法的全部意义在于您尽可能地留在当前线程上”
-
可能是一个单独的问题,但您是否应该在将 requestStream 传递给 StreamWriter 之后,在使用 _apiStreamWriter 之前对其进行处理?
-
作为一般规则,您应该使用
Task.Run而不是Task.Factory.StartNew与 async-await。 -
@i3arnon:你能详细解释一下为什么吗?
-
@KingKerosin stackoverflow.com/a/29693430/885318
标签: c# multithreading asynchronous async-await