我正在尝试理解David Fowler关于
David Fowler在他的声明中是什么意思?他的意思是说,不能从异步任务中使用
Task.Factory.StartNew
+TaskCreationOptions.LongRunning
的说法这里。
我知道在这种情况下使用注意:不要在异步代码中使用TaskCreationOptions.LongRunning,因为这将创建一个新线程,该线程将在第一个await之后被销毁。
Task.Run
或Task.Factory.StartNew
是没有意义的,因为SendLoopAsync和ReceiveLoopAsync完全是异步的。我还知道,如果其中一个方法中有耗时的同步部分,则应该在该方法内使用Task.Run/Task.Factory.StartNew。David Fowler在他的声明中是什么意思?他的意思是说,不能从异步任务中使用
TaskCreationOptions.LongRunning
吗?还是他的意思是说SendLoopAsync/ReceiveLoopAsync不应该是异步的?我也知道TaskCreationOptions.LongRunning意味着任务将立即启动,这不是普通任务所具有的特性,普通任务会被调度程序安排,并可能需要一些时间来启动。当同时启动多个连接时,您可以注意到这种行为,这导致发送和接收循环延迟显着。
public async Task StartAsync(CancellationToken cancellationToken)
{
_ = Task.Factory.StartNew(_ => SendLoopAsync(cancellationToken), TaskCreationOptions.LongRunning, cancellationToken);
_ = Task.Factory.StartNew(_ => ReceiveLoopAsync(cancellationToken), TaskCreationOptions.LongRunning, cancellationToken);
}
private async Task SendLoopAsync()
{
await foreach (var message in _outputChannel.Reader.ReadAllAsync(_cancellationSource?.Token))
{
if (_clientWebSocket.State == WebSocketState.Open)
{
await _clientWebSocket.SendAsync(message.Data.AsMemory(), message.MessageType, true, CancellationToken.None).ConfigureAwait(false);
}
}
}
SynchonousContext
(AsyncContext)添加到该任务线程中,你就可以使用await。 - Trương Quốc Khánh