gpt4 book ai didi

c# - 如何更新我的 API 以使用 async 关键字而不对所有调用者使用 await

转载 作者:太空狗 更新时间:2023-10-29 22:27:11 26 4
gpt4 key购买 nike

我正在尝试移植一些 TcpClient .net 4.5 的依赖代码,使用 StreamSocketDataReader相反。

我有一个名为 ReadLine() 的函数无处不在。通过使用 DataReader在此代码的正文 ( LoadAsync() ) 中,我的方法被强制标记为 async关键字。

链式 react 如下:现在我有数百个地方必须添加 async调用方法并将 await 应用于基础 async方法调用。

这引出了我的下一个问题......有没有一种简单的方法来包装 ReadLine()这样调用方法就不知道它是一个异步方法,这样我就不必更改其余代码了吗?

还有...我经常从多个地方循环使用这个方法调用。如果这些方法现在标记为 async ,恐怕我可能会在不应该的时候从流中读取数据,这会导致各种噩梦。这是一个问题还是我想得太远了?

最佳答案

Also... I often use this method call in a loop, from multiple places. If these methods are now marked async, i'm afraid I might be reading data off a stream when I shouldn't be, which will cause all sorts of nightmares. Is it a problem or am I thinking too far ahead?

如果您在调用*Async 方法时始终使用await,那么您的async 方法将像同步方法一样运行(除了它们赢'阻止)。因此,在循环中使用 await 会像您预期的那样工作。


async 确实通过代码库“增长”。我通常认为这类似于“乌龟一路下来”的古老故事;其他人称它为“僵尸病毒”。

我描述了the deadlock situation在我的博客上有详细介绍。正如我在那里所说,最好的选择是允许 async 增长。

如果您必须创建一个synchronous wrapper for an asynchronous method, see Stephen Toub's advice .您可以使用 Task.Result,但您需要做两件事:

  • 到处使用ConfigureAwait(false)。这将避免僵局。
  • 请注意 Result 具有不同的错误处理语义。

对于您的特定示例,像这样的内容就足够了:

private async Task<string> ReadLineAsync()
{
... // *Every* await in this method and every method it calls
// must make use of ConfigureAwait(false).
}

public string ReadLine()
{
try
{
return ReadLineAsync().Result;
}
catch (AggregateException ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
throw;
}
}

在选择混契约(Contract)步/异步代码库之前,请仔细考虑复杂性。这并不像最初看起来那么容易。

附言一般来说,TCP/IP 代码无论如何都应该是异步的。在套接字上进行连续异步读取通常是个好主意。

关于c# - 如何更新我的 API 以使用 async 关键字而不对所有调用者使用 await,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14186009/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com