I am starting a Thread where an await Task.Run
can be invoked.
After starting a Thread with the ThreadStart.Start
method, why does the await Task.Run
terminate the Thread and Task.Run
does not?
Here is some code as an example:
public async Task Task1()
{
if (awaitRunTask)
{
await Task.Run(async () =>
{
await Test();
}
);
}
else
{
Task.Run(async () =>
{
await Test();
}
);
}
}
In the above example, if a Thread invokes the Task1 method, and awaitRunTask = true
, the Thread terminates. If awaitRunTask = false
, the Thread does not terminate.
When I say terminate, the Thread does not complete correctly and the method where the ThreadStart.Start
is invoked returns. This happens at the await Test()
code.
Why is this and if I want to await a Task.Run
on a Thread, is there a way to do this?
CodePudding user response:
Why is this?
As I explain on my blog, await
here is actually returning to its caller. So the Task1
method returns an incomplete task to its caller, presumably the thread's main method, which presumably is async void
. When the thread's main method returns (due to it's await
), the thread exits.
The core of the problem is that the Thread
type doesn't understand or work naturally with asynchronous code. Thread
is really a very low-level building block at this point and is best avoided in modern code. There are very few scenarios where it can't be replaced with Task.Run
.
if I want to await a Task.Run on a Thread, is there a way to do this?
The easiest solution is to get rid of the legacy thread completely; replace it with Task.Run
.
Otherwise, you need the thread to block. If the continuations can run on thread pool threads, then you can just block directly (e.g., GetAwaiter().GetResult()
). If the continuations need to run on that thread, then use AsyncContext
from my AsyncEx library.
CodePudding user response:
I think because when you do
if (true)
{
await Task.Run(async () =>
{
await Test();
}
);
}
The thread waits until the task run completes because of await , whereas when you do
Task.Run(async () =>
{
await Test();
}
);
A task is run on a thread (which may be the current thread), but your code does not wait until the task completes. That may explain why the thread does not finish. Hope this helps.