【发布时间】:2021-01-25 06:37:07
【问题描述】:
我有一个关于异步等待模式的问题。我有以下代码
internal async Task<int> ConsumedBytesAsync(byte[] buffer)
{
while(condition)
{
//build message
if (message != null)
{
if (_previousRegisterMessageTask != null)
{
await _previousRegisterMessageTask;
}
_previousRegisterMessageTask = _controllers.RegisterMessageAsync(message, chunk.MessageHeader.MessageStreamId);
}
}
return totalConsumed;
}
还有其他类的代码。
internal async Task RegisterMessageAsync(IMessage message, uint messageid)
{
// some stuff about retrieve resposible controller
if (controller != null)
{
await controller.HandleMessage(message, action);
}
}
我想通过异步运行 RegisterMessage 来提高性能,同时开始构建下一条消息。构建下一条消息时,应该等待完成前一条消息的注册。在理想情况下,它应该可以正常工作,但实际上 _controllers.RegisterMessageAsync 方法是同步执行的。
我已经通过 Stopwatch start 和 stop 围绕该方法进行了检查(我假设经过的时间应该在 0 - 5 左右,因为应该完成的唯一操作是返回并保存 Task,但平均执行时间是 800-900这个方法的时间)和_controllers.RegisterMessageAsync中的Control.WriteLine在等待之后和将Task保存到_previousRegisterMessageTask之后(首先出现来自_controllers.RegisterMessageAsync的Control.WriteLine。)
所以请让我知道为什么该操作同步而不是异步工作,以及我可以做些什么来实现上面描述的逻辑。也许我做了错误的测试并且它是异步工作的? 提前致谢。
【问题讨论】:
-
while 循环对任务有等待。这使得它是连续的。 (请注意,异步和同步之间存在差异)。所以——你能在你的代码中准确地标记你想要测量的东西吗?作为MVP?因为在当前设置下,我很想将行为归咎于循环中的等待。
-
是的,当然。正如我上面提到的,我想同时注册消息并构建下一条消息。我测量了这行的时间执行 -> _previousRegisterMessageTask = _controllers.RegisterMessageAsync(message, chunk.MessageHeader.MessageStreamId); -> 通过秒表。我认为该行的执行应该是 0-5 的经过时间,因为应该只有返回任务并保存在 _previousRegisterMessageTask 但时间不同。运行时间为 800-900,这是此方法的平均执行时间。
-
"_controllers.RegisterMessageAsync 方法同步执行。" -> 完全不正确。您将异步操作与即发即弃处理混淆了。假设
HandleMessage是异步的,那么整个代码都是异步工作的。另外,请注意_controllers.RegisterMessageAsync或多或少在_previousRegisterMessageTask被赋值时开始执行。
标签: c# asynchronous multitasking