我有一个包含 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
没有Foo
和 FooAsync
这里可能有相似但不同的实现 - 一种旨在利用异步,一种完全同步工作。通过调用另一个来欺骗一个是不是一个好主意——“sync over async”(同步版本调用异步版本)和“async over sync”(异步版本调用同步版本) ) 是反模式,应该避免(第一个比第二个更有害)。
如果你真的不想这样做,你也可以做一些事情,比如添加 FooCompleted
回调事件(或类似事件),但是:这仍然是根本上的签名更改,调用者仍然必须以不同的方式使用 API。当你这样做的时候 - 你还不如通过添加 Task<T>
让消费者更容易API 而不是。
关于c# - 如何在不更改签名的情况下将同步方法转换为异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54074060/