Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Task<int> become an int?

We have this method:

async Task<int> AccessTheWebAsync() {      HttpClient client = new HttpClient();     Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");     // You can do work here that doesn't rely on the string from GetStringAsync.    DoIndependentWork();     string urlContents = await getStringTask;    //The thing is that this returns an int to a method that has a return type of Task<int>    return urlContents.Length; } 

Does an implicit conversion occur between Task<int> and int? If not, then what is happening? How is it implemented to work?

like image 489
Freeman Avatar asked Oct 31 '12 13:10

Freeman


People also ask

What does a Task return C#?

Async methods can have the following return types: Task, for an async method that performs an operation but returns no value. Task<TResult>, for an async method that returns a value. void , for an event handler.

What happens when a method returns a Task without awaiting it?

An exception that's raised in a method that returns a Task or Task<TResult> is stored in the returned task. If you don't await the task or explicitly check for exceptions, the exception is lost. If you await the task, its exception is rethrown. As a best practice, you should always await the call.

How do I return a Boolean Task?

To return Boolean from Task Synchronously, we can use Task. FromResult<TResult>(TResult) Method. This method creates a Task result that's completed successfully with the specified result. The calling method uses an await operator to suspend the caller's completion till called async method has finished successfully.


1 Answers

Does an implicit conversion occur between Task<> and int?

Nope. This is just part of how async/await works.

Any method declared as async has to have a return type of:

  • void (avoid if possible)
  • Task (no result beyond notification of completion/failure)
  • Task<T> (for a logical result of type T in an async manner)

The compiler does all the appropriate wrapping. The point is that you're asynchronously returning urlContents.Length - you can't make the method just return int, as the actual method will return when it hits the first await expression which hasn't already completed. So instead, it returns a Task<int> which will complete when the async method itself completes.

Note that await does the opposite - it unwraps a Task<T> to a T value, which is how this line works:

string urlContents = await getStringTask; 

... but of course it unwraps it asynchronously, whereas just using Result would block until the task had completed. (await can unwrap other types which implement the awaitable pattern, but Task<T> is the one you're likely to use most often.)

This dual wrapping/unwrapping is what allows async to be so composable. For example, I could write another async method which calls yours and doubles the result:

public async Task<int> AccessTheWebAndDoubleAsync() {     var task = AccessTheWebAsync();     int result = await task;     return result * 2; } 

(Or simply return await AccessTheWebAsync() * 2; of course.)

like image 158
Jon Skeet Avatar answered Sep 22 '22 17:09

Jon Skeet