C# 中有没有办法在不使调用者也异步的情况下调用异步方法? [复制]

Posted

技术标签:

【中文标题】C# 中有没有办法在不使调用者也异步的情况下调用异步方法? [复制]【英文标题】:Is there a way in C# to make a call to an async method without making the caller also async? [duplicate] 【发布时间】:2016-11-23 00:03:49 【问题描述】:

为了更清楚,我引用了一个以前不是异步的工厂方法。在最近的 API 升级中,他们废弃了旧方法并创建了一个新的异步方法。现在,我们的代码库最初来自 VS2010,当时异步还不存在。我想将方法​​调用更改为新版本,这样我们就不会抛出弃用警告。

现在问题来了:对异步方法的任何调用似乎都需要“等待”,以保证该方法实际完成并且在该方法中初始化的任何状态数据都可用于后续操作。但是,在调用中放置“await”要求调用方法也是异步的,这就要求该方法的调用者也使用await,依此类推,一直到调用堆栈的顶部。我发现避免这种情况的唯一方法是将异步工厂方法的调用放在 void 异步方法中。但是,Microsoft 已明确表示该功能仅适用于事件处理程序,否则应避免使用。

现在,我确实可以调整调用堆栈中的每个函数。但这不仅令人讨厌,而且是一种极端的封装违规行为。为什么一个***类必须改变它的方法头,只是因为一些对 27 层以下的函数的调用必须处理外部 API 更改?我怀疑我遗漏了一些非常明显的东西,但从它的外观来看,我有两个选择:要么更改所有方法头,要么提交“糟糕的编程习惯”。还有其他方法吗?提前感谢您的任何意见。

【问题讨论】:

这就是异步的工作方式。你可以直接使用Task,但这对你没有帮助。 换句话说,异步不仅仅是一个实现细节;这是调用操作(或者更确切地说是获得响应)的不同方式。 你并不孤单。 cdn.meme.am/instances/35796044.jpg 【参考方案1】:

还有其他方法吗?

不是真的。函数调用是同步的(根据定义,阻塞线程),或者函数调用是异步的(根据定义,不阻塞线程)。一个线程不可能同时被阻塞而不被阻塞。

我建议您升级您的代码以使用async。这是最好的长期解决方案。或者,您可以关闭过时警告,或使用旧版本的库。

也就是说,我确实写了an article on brownfield async development,它说明了各种部分异步方法以及每种方法的缺点(剧透:没有完美的解决方案)。

【讨论】:

我明白你在说什么。我只是希望有一种方法可以告诉 .NET,“是的,我知道它是异步的,但是对于这个调用,假装它不是。”正如你所说,继续开始让整个程序异步可能不是一个坏主意。

以上是关于C# 中有没有办法在不使调用者也异步的情况下调用异步方法? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使 main() 异步的情况下将异步对象注册到 get_it 包?

在不使用 COM 的情况下从 C++ 调用 C# 方法

如何在不使项目变灰的情况下禁用 UITabBarItem

Unix环境高级编程(十五)高级I/O

您可以在不使其无状态的情况下将 Spring Security 与 REST 服务一起使用吗?

在 perl 中如何在不使用 XS 的情况下写入调用者的变量?