Home > Enterprise >  Why does an async Task.Run terminate a Thread and a Task Run does not?
Why does an async Task.Run terminate a Thread and a Task Run does not?

Time:08-22

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.

  • Related