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?
EDIT
Here is some code to show a more detailed example:
public class ThreadExample
{
public bool awaitRunTask;
public string value;
private async Task StartThreadAsync()
{
var method = this.GetType().GetMethod("RunTasksAsync");
ThreadStart threadStart;
threadStart = async () =>
{
await InvokeAsync(method, this, null);
};
var thread = new Thread(threadStart);
thread.Start();
thread.Join();
}
public async Task RunTasksAsync()
{
await Task1Async();
Task2();
}
private async Task Task1Async()
{
if (awaitRunTask)
{
await Task.Run(async () =>
{
await TestAsync();
}
);
}
else
{
Task.Run(async () =>
{
await TestAsync();
}
);
}
}
private void Task2()
{
value = "valid";
}
private async Task TestAsync()
{
await Task.Delay(1000);
}
private async Task InvokeAsync(MethodInfo method, object instance, object[] parameters)
{
dynamic awaitable = method.Invoke(instance, parameters);
await awaitable;
}
public async Task ValueIsCorrectAsync()
{
value = "not valid";
awaitRunTask = false;
await StartThreadAsync();
var isCorrect = (value == "valid");
}
public async Task ValueIsNotCorrectAsync()
{
value = "not valid";
awaitRunTask = true;
await StartThreadAsync();
var isCorrect = (value == "valid");
}
}
The ValueIsCorrectAsync
method works correctly as the Task2
method sets the value
field.
The ValueIsNotCorrectAsync
method does not work correctly as the await Task.Run
in the Task1Async
method interferes with the Thread. The StartThreadAsync
method returns before the Task2
method sets the value
field.
The only difference between the two methods, is the value of awaitRunTask
.
How should I change my code such that the value
field is set correctly when awaitRunTask = true
?
EDIT3
If the await Task.Delay(1000);
is commented out in the TestAsync
method, the code works for both awaitRunTask = true
and awaitRunTask = false;
Can someone please explain to me why? I need to know why because the TestAsync
method needs to be able to run asynchronous code.