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?
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.
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.
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.
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With