本文介绍了如何在不更改签名的情况下将同步方法转换为异步方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有40个模块的大型C#解决方案.

I have a large scale C# solution with 40-ish modules.

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

I'm trying to convert a service used solution-wide from synchronous to asynchronous.

问题是我无法找到一种方法来改变方法的签名.

the problem is I can't find a way to do so without changing the signature of the method.

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

I've tried wrapping said asynchronous desired operation with Task but that requires changing the method signature.

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

I've tried changing the caller to block itself while the method is operating but that screwed my system pretty good because it's a very long calling-chain and changing each of the members in the chain to block itself is a serious issue.

public SomeClass Foo()
{
// Synchronous Code
}

将其转换为:

public SomeClass Foo()
{
//Asynchronous code
}

所有呼叫者保持不变

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

推荐答案

从根本上将某些内容从同步更改为异步的任何实现都将涉及签名更改.任何其他方法都无法很好地发挥作用.从根本上讲:异步和同步需求不同的API,这意味着:不同的签名.这是不可避免的,并且坦率地说如何在不更改签名的情况下将同步方法转换为异步方法?"是一个无法解决的问题(很可能是错误的问题).很抱歉,如果我似乎没有在此处回答问题,但是...有时答案是您不能,任何说您可以做到的人都在诱使您走上一条非常糟糕的道路".

Any implementation that fundamentally changes something from sync to async is going to involve a signature change. Any other approach is simply not going to work well. Fundamentally: async and sync demand different APIs, which means: different signatures. This is unavoidable, and frankly "How to convert synchronous method to asynchronous without changing it's signature?" is an unsolvable problem (and more probably: the wrong question). I'm sorry if it seems like I'm not answering the question there, but... sometimes the answer is "you can't, and anyone who says you can is tempting you down a very bad path".

async / Task< T> 而言,在不破坏兼容性的情况下执行此操作的最常见方法是添加一个新的/单独的方法,因此您拥有

In the async/Task<T> sense, the most common way to do this without breaking compatibility is to add a new / separate method, so you have

SomeReturnType Foo();

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

这里的 Foo FooAsync 可能没有相似但不同的实现-一种旨在利用异步的方法,一种完全同步工作的方法.通过调用另一个来欺骗一个是一个好主意-既异步同步"(称为异步版本的同步版本)又是异步异步"(称为同步版本的异步版本))是反模式,应避免使用(第一种比第二种有害得多).

nothing that Foo and FooAsync here probably have similar but different implementations - one designed to exploit async, one that works purely synchronously. It is not a good idea to spoof one by calling the other - both "sync over async" (the synchronous version calling the async version) and "async over sync" (the async version calling the sync version) are anti-patterns, and should be avoided (the first is much more harmful than the second).

如果您真的不想这样做,您也可以执行类似添加 FooCompleted 回调事件(或类似的回调事件)的操作,但是:从根本上说,这仍然是签名更改,调用者仍将不得不不同地使用API​​.在完成此操作时-您可能还可以通过添加 Task< T> API来简化消费者的工作.

If you really don't want to do this, you could also do things like adding a FooCompleted callback event (or similar), but : this is still fundamentally a signature change, and the caller will still have to use the API differently. By the time you've done that - you might as well have made it easy for the consumer by adding the Task<T> API instead.

这篇关于如何在不更改签名的情况下将同步方法转换为异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 14:56