Creating an async method in .NET 4.0 that can be u

2019-01-30 18:28发布

问题:

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

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.

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

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?

回答1:

As others have stated, you start by having a method return Task or Task<TResult>. This is sufficient to await its result in .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.

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

  • If you have existing IAsyncResult-based asynchronous methods, use Task.Factory.FromAsync.
  • If you have another asynchronous system, use TaskCompletionSource<TResult>.


回答2:

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

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).

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).

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.



回答3:

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.

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.TaskCompletionSource to construct a task, use Begin/End model of asynchronous methods to execute whatever you need to execute. Then, when you have the result on hand, post it to the previously constructed Task instance using your completion source.

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.