Archive

This is my first blog :), so please excuse me (or point me) for any fault.

Whenever something new comes I usually analyze it in my own way figuring out its good and bad and whys. This is the first time I am thinking aloud via blogs.

Something wrong with async, await and the Task(Task<T>)

There is something wrong with the method modifier (async) and operator (await), something is not in place

Somehow I feel that async, await and Task triplet does not fit in the language rules and expectations

Lest analyze this in three parts –

1.Analyze method invocation statement.

2.Analyze method declaration statement

3.Analyze method return statement.

1. Analyze method invocation statement –

Consider these two statements

Task<int> u =ReturnIntAsync();

intt = await ReturnIntAsync();

Expected – LHS and RHS must be of same data type.

first statement, no problem there, it clearly states that ReturnIntAsync() method must have Task<int> as return type and this is the case. Second statement, no problem, it looks like await must be pulling out the Result, which is int, from Task and returning it (in addition to its actual functionality, that is, returning back to the caller after asynchronously invoking the ReturnIntAsync() method).

So Actual – LHS and RHS are of same data type.

2. Analyze method declaration statement –

The method declaration –

asyncpublicstaticTask<int> ReturnIntAsync()

Expected – Must match with the caller in terms of return type and function prototype.

There are three method modifiers in this statement, static only one copy of this method will be created, public it’s a no restriction access modifier, async marks the method for asynchronous calling.

Expected – it must match with the of return statement of function definition

Now take a look at the method body –

asyncpublicstaticTask<int> ReturnIntAsync()

{

return0;

}

No need to discuss anything its clearly not matching. By no means the value zero(0) can be thought of implicitly converted to Task<int>.

Actual – both are different.

So, async modifier is responsible of this mis-behavior.

Why

So, before asking the question lets analyze the situation and try some alternatives.

First alternative that comes to my mind is to simply change the function definition to return int instead of Task<int> and let the compiler automatically takes care of int and Task<int>. But that’s not possible because at the callers end Task<int> is not getting converted to int by using the await keyword, it’s Task<int>.Result which is an int (see point 1 – analysis of caller). Also, it’s the method which is creating a task and returning it and not the caller who is creating the task out of int.

Second alternative, we can have a special kind of return statement like async return or task return, which will return the Task<int> instead of int. See below examples –

asyncpublicstaticTask<int> ReturnIntAsync()

{

return0; //instead

async return0; //use this

task return0; //or this

returntask 0; //or this

returnasync 0; //or this

}

Now this will make sense, as we are applying some operator to the returning value which can be assumed attaching the return value to the task. At first I thought that just for the sake of readability and making the statement complete should we introduce a new keyword. But then I thought why not if you recall as soon as you apply the async modifier the method is no more returning what it was returning previously instead it is attaching the value of return to the task.

So to conclude I strongly think that something must be done with the return statement. I am sure it must be a big pain to change something in the language but that’s my view with the potential problem and the solution :).