C# 在 .NET 4.0 中创建可与 .NET 4.5 中的“await”一起使用的异步方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9574790/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 07:57:20  来源:igfitidea点击:

Creating an async method in .NET 4.0 that can be used with "await" in .NET 4.5

c#.netasync-await.net-4.5

提问by James Newton-King

I have a .NET project that uses C# in .NET 4.0 and VS2010.

我有一个在 .NET 4.0 和 VS2010 中使用 C# 的 .NET 项目。

What I would like to do is add some async overloads to my library to make doing async programming easier for users in .NET 4.5 with the await keyword. Right now the methods that are being overloaded are non-asynchronous. Also I don't want to use any async methods myself, just create new ones and make them available.

我想要做的是向我的库中添加一些异步重载,以便使用 await 关键字使 .NET 4.5 中的用户更容易进行异步编程。现在正在重载的方法是非异步的。此外,我不想自己使用任何异步方法,只需创建新方法并使其可用。

Is creating async methods in .NET 4.0 and VS2010 possible and if so, what should the .NET 4.0 async method look like?

是否可以在 .NET 4.0 和 VS2010 中创建异步方法,如果可以,.NET 4.0 异步方法应该是什么样的?

Because I'm using VS2010 I don't have access to the "async" keyword so what needs to happen to emulate that behavior in .NET 4.0? For example does it need to return any particular type, and does any code need to happen inside the method to make the currently non-asynchronous code it is calling happen asynchronously?

因为我使用的是 VS2010,所以我无法访问“async”关键字,那么在 .NET 4.0 中模拟该行为需要做什么?例如,它是否需要返回任何特定类型,以及是否需要在方法内部发生任何代码以使其调用的当前非异步代码异步发生?

采纳答案by Stephen Cleary

As others have stated, you start by having a method return Taskor Task<TResult>. This is sufficient to awaitits result in .NET 4.5.

正如其他人所说,您首先拥有一个方法 returnTaskTask<TResult>。这足以await在 .NET 4.5 中产生结果。

To have your method fit in as well as possible with future asynchronous code, follow the guidelines in the Task-based Asynchronous Pattern document(also available on MSDN). It provides naming conventions and parameter recommendations, e.g., for supporting cancellation.

为了让您的方法尽可能适合未来的异步代码,请遵循基于任务的异步模式文档(也可在 MSDN 上找到)中的指南。它提供命名约定和参数建议,例如,用于支持取消。

For the implementation of your method, you have a few choices:

对于您的方法的实现,您有几个选择:

回答by usr

The simplest way to do this is to return a Taskor a Task<T>. That will be enough.

最简单的方法是返回 aTask或 a Task<T>。那就足够了。

However this only makes sense if your method really executes asynchronously.

但是,这仅在您的方法真正异步执行时才有意义。

I also recommend that you follow the usual pattern of naming them like AbcAsync ("Async" suffix). Your callers will not notice any difference to an async method created with C# 5 (because there is none).

我还建议您按照通常的模式将它们命名为 AbcAsync(“Async”后缀)。您的调用者不会注意到与使用 C# 5 创建的异步方法有任何区别(因为没有)。

Tip: Just adding async to the method does nothing. Your method will execute sequentially and return a completed task. Making the method return a task must serve a certain purpose - usually this is done because the method inherently executes asynchronously (like a web-service call or file IO).

提示:只是向方法添加 async 什么都不做。您的方法将按顺序执行并返回一个已完成的任务。使方法返回一个任务必须服务于某个目的——通常这样做是因为该方法本质上是异步执行的(如 Web 服务调用或文件 IO)。

If your method only contains computation but no IO (or only blocking IO) it is usually better not to make it async because you gain nothing doing that. Async methods do not always execute on a separate thread. If that last sentence surprised you, you may want to dig a little into this topic.

如果您的方法仅包含计算但没有 IO(或仅阻塞 IO),通常最好不要使其异步,因为这样做您一无所获。异步方法并不总是在单独的线程上执行。如果最后一句话让您感到惊讶,您可能想深入研究一下这个话题。

回答by Ekin Koc

As long as you return a Task that completes somehow (whether in a thread or asynchronously), you would support the async model..

只要您返回以某种方式完成的任务(无论是在线程中还是异步),您就会支持异步模型..

Having a Task execute asynchronously is another story. If you had access to the async keyword and the API you could simply base your method on async calls to other, already supplied async methods. But in this case, you have to hand-craft your async Tasks.

异步执行任务是另一回事。如果您可以访问 async 关键字和 API,您可以简单地将您的方法基于对其他已提供的异步方法的异步调用。但在这种情况下,您必须手工制作异步任务。

There might be better ways to do it, but the most elegant way I can see (and have used) is to utilize System.Threading.Tasks.TaskCompletionSourceto construct a task, use Begin/Endmodel of asynchronous methods to execute whatever you need to execute. Then, when you have the result on hand, post it to the previously constructed Taskinstance using your completion source.

可能有更好的方法来做到这一点,但最优雅的方式,我可以看到(和已经使用)是利用System.Threading.Tasks.TaskCompletionSource构建的任务,使用Begin/End异步方法执行任何你需要执行的模式。然后,当您手头有结果时,Task使用完成源将其发布到先前构造的实例。

It will certainly be asynchronous, just not as fancy as the ones in upcoming release.

它肯定是异步的,只是不像即将发布的那样花哨。

Disclaimer:I'm no way near an expert on this. Just made some experiments on.

免责声明:我远不是这方面的专家。刚刚做了一些实验。