Reputation: 13
I'm trying to use following async extention method:
public static async Task<MyClass<T>> ToMyClass<T>(this Task<T> source)
{
\\ some logic
return new MyClass<T>(await source);
}
by writing this test method:
public async void Test()
{
Task<int> task = new Task<int>(() => 10);
var result = await task.ToMyClass();
task.Start();
Assert.True(result.Value == 10);
}
But all I've got is infinite waiting. I have tried remove await keyword, apply it to task like this (await task).ToMyClass()
, but it leaded me only to infinite waiting or exceptions.
When I changed usage of task
to Task.Run method:
var result = await Task.Run(() => 10).ToMyClass();
everything worked well.
What am I doing wrong while using constructor and Start()
method? And what is the difference beetween these two ways?
Upvotes: 1
Views: 482
Reputation: 1424
So, you try to wait before start.
var result = await task.ToMyClass();
task.Start();
You should start it before awaiting
Upvotes: 0
Reputation: 24459
There are a couple of differences here.
As @GSerg has mentioned in the comment, the Task
constructors are a bit special because they create a "cold" task that doesn't run until you explicitly start it with the Start
method. Relevant info from the docs:
Tasks that are created by the public Task constructors are referred to as cold tasks, because they begin their life cycle in the non-scheduled Created state and are scheduled only when Start is called on these instances.
With that explanation, it becomes obvious why you're waiting infinitely: because you're waiting on something that hasn't started yet, and so is never going to complete.
So if you swap the order of your task.Start();
and var result = await task.ToMyClass();
lines, starting the task before waiting on it, that should solve the infinite wait issue:
public async void Test()
{
Task<int> task = new Task<int>(() => 10);
task.Start();
var result = await task.ToMyClass();
Assert.True(result.Value == 10);
}
Note that while Task.Run
gives you a "hot"(started) task, which doesn't have that problem, it also has a different effect, in that it schedules whatever you pass to it to a Thread Pool thread (not a good idea server-side like ASP.NET), whereas Tasks, in general, don't necessarily involve threads.
Upvotes: 2