Reputation: 9870
In what situation would you return a Task<T>
without using async
in the method signature?
I've got such a method in the below code but am having trouble understanding what's going on.
Why does my example code below not execute past any of the await
statements?
ie. why do Console.WriteLine("4)");
and Console.WriteLine("3)");
and return x;
never get executed?
class Program
{
static void Main(string[] args)
{
TestAsync testAsync = new TestAsync();
testAsync.Run();
Console.Read();
}
}
public class TestAsync
{
public async void Run()
{
Task<int> resultTask = GetInt();
Console.WriteLine("2)");
int x = await resultTask;
Console.WriteLine("4)");
}
public async Task<int> GetInt()
{
Task<int> GetIntAfterLongWaitTask = GetIntAfterLongWait();
Console.WriteLine("1)");
int x = await GetIntAfterLongWaitTask;
Console.WriteLine("3)");
return x;
}
public Task<int> GetIntAfterLongWait()
{
Task.Run(() =>
{
for (int i = 0; i < 500000000; i++)
{
if (i % 10000000 == 0)
{
Console.WriteLine(i);
}
}
});
Console.WriteLine("Returning 23");
return new Task<int>(() => 23);
}
}
/*
Output is:
Returning 23
1)
2)
<list of ints>
*/
Upvotes: 3
Views: 896
Reputation: 5240
When you return a Task
from a non-async
method?
Task<T>
is generalized spoken a promise for a future value. Whether you produce this promise from an async
keyworded method or from another source (like a started thread or IO callbacks) is not of interest for the caller and only an implementation strategy. That is also the reason, why interfaces (or abstract method definition) do not have the async
keyword at all (async
/await
is an implementation strategy).
Your code sample
GetIntAfterLongWait
is flawed in two ways. The first instantiated Task
is instantiated and off-loaded to a thread, but the result is never picked up (so never awaited ... and never delaying anything).GetIntAfterLongWait
) is created (by the constructor with a method to execute) but not started (Task.Start()
). Other more simplier methods are the static Task.Run
or (in this case) Task.FromResult
. The task (or promise) never delivers the result, because the function block in the constructor is never executed.Main
method does not await the result of the returned task (either by await
or Task.Wait()
or Task.Result
.Upvotes: 6
Reputation: 9519
The problem in your code is that you are actually await
never started task since the method GetIntAfterLongWait
returns new instance of the task which is not started. So basically you have a deadlock, waiting for something which is not started at all.
You could return Task.FromResult(23)
which is basically already completed task, or you could actually run your task Task.Run<int>(() => 23);
Upvotes: 2
Reputation: 1718
You are likely creating a new thread in the GetIntAfterLongWait()
method. Try changing return new Task<int>(() => 23);
to return Task.FromResult(23);
.
For more information on Task.FromResult
see the MSDN Documentation (with a good example) on How to: Create Pre-Computed Tasks
Upvotes: 0