Using Async-Await on .Net 4

How to properly use async/await in .NET 4.0

In the older versions of WCF the async functions where tied to Begin/End statements. Using the task based async proxes will likely cause problems like you are running in to.

Regenerate your client proxies so you have the Begin/End combos and use TaskFactory.FromAsync to convert it in to a task which can be awaited on using Microsoft.Bcl.Async.

//put this in a seperate file, client proxies are usually marked "partial" so you can 
// add functions on like this and not have them erased when you regenerate.
partial class YourClientProxy
{
public Task<DataTable> ProcessSomethingAsync(string Param1, int Param2)
{
return Task<DataTable>.Factory.FromAsync(this.BeginProcessSomething, this.EndProcessSomething, Param1, Param2, null);
}
}

async/await keywords not available in .net 4.0

You're not going to get a better answer than Jon Skeet's.

The only supported way to do this is to use VS2012 with Microsoft.Bcl.Async.

VS2010 is very difficult to get working with async/await. There was an old Async CTP package (which had many bugs that were never fixed) that acted as an "add-on"/"partial replacement" to VS2010. However, that package never worked well with the VS2010 updates. So, you'd have to first find a version of one of the old CTP installers, play around with installing some VS updates, and then see if the CTP works. If you've already installed all your VS2010 updates then no version of the CTP will work. I think once you find an update situation where you can install a working CTP, then you can install the other updates.

After all this work, you'll still end up with a bug-ridden (and definitely unoptimized) implementation of async.

Or, you can do as Jon Skeet suggested and download the free version of VS2012 Express with Microsoft.Bcl.Async and have a fully supported solution.

Using async-await on .net 4

Microsoft released the Async Targeting Pack (Microsoft.Bcl.Async) through Nuget as a replacement for the AsyncCTP.

You can read more about it here: http://blogs.msdn.com/b/bclteam/archive/2013/04/17/microsoft-bcl-async-is-now-stable.aspx.

You can read about the previous version here: http://blogs.msdn.com/b/lucian/archive/2012/04/24/async-targeting-pack.aspx.

As this pack is officially supported, I now believe the best option for targeting XP + async would be using Visual Studio 2012 + C#5 + Async Targeting Pack.

If you feel the need to target .NET 3.5 though, you can still use (my) AsyncBridge for .NET 3.5.

C# Task.Run equivalent in .NET 4.0

async/await is .NET 4.5.
You need to install Microsoft.Bcl.Async for it to work in 4.

Await/Async .net 4.0

.Net 4.0 supports await perfectly fine with the compatibility pack.

However, ASP.Net 4.0 does not, because it makes far more assumptions about the async model.

Using await in ASP.Net requires a better SynchronizationContext, which was added in 4.5.

How Async/await works in .net 4.5

Async and await works with the Task Library. If you write a method and want to make it async you just have to mark it as async and call await on any task inside of your method. Just the await keyword make your method async and just this code runs async. For example:

//This Method isn't async because there is no await
private async Task DoSomething()
{
//Some work
}

//This method is async because it awaits sth.
private async Task DoSomething()
{
await SomeOtherStuff();
}

Note that async methods return Task or Task which encapsulate your return type. This Task allows other methods to await your method. Up to this way you build a chain which ends in your GUI. So you GUI isn't blocking and responsive.

I found this diagram after 1 sec of google which describe this behaviour pretty well:

Sample Image

This has not much to do with BeginInvoke and EndInvoke, because Invoke calls are just for using Gui objects in different threads. If possible you should avoid BeginInvoke and EndInvoke and use the GUI only on your Mainthread.

What are the benefits of async/await in ASP.NET requests?


When await CallAllAsync() is called, a Task instance is taken from a Task pool and the code inside CallAllAsync() is run. Lets say the thread for that task is Thread_All. This pauses the parentThread_Get and it will not run until Thread_All is completed.

This is not correct. When CallAllAsync() is called, it is executed synchronously until the first await is reached. At this point a Task is created (there is no pool) that represents the remainder of the method (the "continuation"). Then the task is returned to the caller.

My question is, since all of this run inside a new thread for that ASP.NET Core endpoint, and all of the calls are sequential, are there any performance benefits from using async/await in this code?

There are no immediate benefits to the current request, since the operations have to happen in series, and each of them takes a certain amount of time to complete. However, using this kind of async logic allows the thread to be surrendered to other requests while waiting for these async tasks to complete. This gives your overall application better throughput, and thereby benefits all requests.

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

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

c# fire and forget async method: implement yield() in .net 4

Based on @Evk message I have tried this:

Task MessageAsync(string message, DateTime date, CancellationToken token)
{
var messageToLog =$"At {date.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture)}: {message}";
Task.Factory.StartNew(() => _logger.Info(messageToLog), token);
}


Related Topics



Leave a reply



Submit