This is a mirror of official site: http://jasper-net.blogspot.com/

Decompiling Async/Await

| Tuesday, March 19, 2013
Inline image 2

You can get the async-enabled ILSpy build from our build server.

The async support is not yet complete; for example decompilation fails if the IL evaluation stack is not empty at the point of the await expression.

The decompilation logic highly depends on the patterns produced by the C# 5 compiler - it only works with code compiled with the C# compiler in the .NET 4.5 beta release, not with any previous CTPs. Also, it is likely that ILSpy will need adjustments for the final C# 5 compiler.

While testing, I found that the .NET 4.5 beta BCL was not compiled with the beta compiler - where the beta compiler uses multiple awaiter fields, the BCL code uses a single field of type object and uses arrays of length 1. This is similar to the code generated by the .NET 4.5 developer preview, so my guess is that Microsoft used some internal version in between the developer preview and the beta for compiling the .NET 4.5 beta BCL. For more information, take a look at Jon Skeet's description of the async codegen changes.
This means the ILSpy cannot decompile async methods in the .NET 4.5 beta BCL. This problem should disappear with the next .NET 4.5 release (.NET 4.5 RC?).

So how does ILSpy decompile async methods, then? Consider the compiler-generated code of the move next method:

// Async.$AwaitInLoopCondition$d__17
void IAsyncStateMachine.MoveNext()
{
    try
    {
        int num = this.$1__state;
        TaskAwaiter<bool> taskAwaiter;
        if (num == 0)
        {
            taskAwaiter = this.$u__$awaiter18;
            this.$u__$awaiter18 = default(TaskAwaiter<bool>);
            this.$1__state = -1;
            goto IL_7C;
        }
        IL_23:
        taskAwaiter = this.$4__this.SimpleBoolTaskMethod().GetAwaiter();
        if (!taskAwaiter.IsCompleted)
        {
            this.$1__state = 0;
            this.$u__$awaiter18 = taskAwaiter;
            this.$t__builder.AwaitUnsafeOnCompleted<TaskAwaiter<bool>, Async.$AwaitInLoopCondition$d__17>(ref taskAwaiter, ref this);
            return;
        }
        IL_7C:

QR: Inline image 1

Posted via email from Jasper-net

0 comments: