c# - 如何在不更改签名的情况下将同步方法转换为异步方法

标签 c# asynchronous task synchronous

我有一个包含 40 个模块的大型 C# 解决方案。

我正在尝试将解决方案范围内使用的服务从同步转换为异步。

问题是我无法在不更改方法签名的情况下找到这样做的方法。

我已经尝试用 Task 包装所述异步所需操作,但这需要更改方法签名。

我曾尝试更改调用方以在方法运行时阻止自身,但这把我的系统搞砸了,因为它是一个非常长的调用链,并且更改链中的每个成员以阻止自身是一个严重的问题。

public SomeClass Foo()
{
// Synchronous Code
}

把它变成:

public SomeClass Foo()
{
//Asynchronous code
}

所有来电者保持不变

public void DifferentModule()
{
 var class = Foo();
}

最佳答案

任何从根本上将某些内容从同步更改为异步的实现都将涉及签名更改。任何其他方法都不会奏效。从根本上说:异步和同步需要不同的 API,这意味着:不同的签名。这是不可避免的,坦率地说“How to convert synchronous method to asynchronous without changing its signature?”是一个无法解决的问题(更可能是:错误的问题)。如果看起来我没有回答那里的问题,我很抱歉,但是......有时答案是“你不能,任何说你可以的人都是在引诱你走上一条非常糟糕的道路”。


async/Task<T>从某种意义上说,在不破坏兼容性的情况下执行此操作的最常见方法是添加一个新的/单独的方法,因此您有

SomeReturnType Foo();

Task<SomeReturnType> FooAsync(); // or ValueTask<T> if often actually synchoronous

没有FooFooAsync这里可能有相似但不同的实现 - 一种旨在利用异步,一种完全同步工作。通过调用另一个来欺骗一个是不是一个好主意——“sync over async”(同步版本调用异步版本)和“async over sync”(异步版本调用同步版本) ) 是反模式,应该避免(第一个比第二个更有害)。


如果你真的不想这样做,你也可以做一些事情,比如添加 FooCompleted回调事件(或类似事件),但是:这仍然是根本上的签名更改,调用者仍然必须以不同的方式使用 API。当你这样做的时候 - 你还不如通过添加 Task<T> 让消费者更容易API 而不是。

关于c# - 如何在不更改签名的情况下将同步方法转换为异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54074060/

相关文章:

c# - 我如何正确地将数据从 wordpress mySQL DB 解析为 xamarin forms c#?

c# - 重构 Linq 代码和 "LINQ to Entities does not recognize the method"

c# - .Net MTP/PTP 包装器?

C++ - OpenMP 任务 - map 插入,关键吗?

synchronization - 如何让许多 FreeRTOS 任务等待彼此完成初始化

c# - API请求WaitingForActivation "Not yet computed"错误

c# - 用于 UDP 服务器的 C# 可等待 SocketAsyncEventArgs 包装器; socket.ReceiveAsync 返回无效的 RemoteEndPoint (0.0.0.0 :0)

javascript - 多次异步服务调用后的 AngularJS 函数

asp.net-mvc - 在 Action 内的单独线程上运行方法

python - Windows 任务计划程序,python 脚本,代码 2147942401