I'm investigating async/await
.
And I had a question at C# winform: what's wrong in this async example if access result before await The above question has been resolved. This is a deadlock issue.
But when I searched some question in stackoverflow. I found this: async/await different thread ID
It should be also a deadlock issue, isn't it?
I rewrite a similar code to test
private async void button1_Click(object sender, EventArgs e)
{
TB_Log(tbMsg, "click start, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
Task task = func1();
TB_Log(tbMsg, "click wait, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
await task;
TB_Log(tbMsg, "click end, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
}
private async Task func1()
{
TB_Log(tbMsg, "func1 start, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
await Task.Run(() =>
{
TB_Log(tbMsg, "func1 task.run, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
Task<int> task = func2();
if (task.Result == 5) { ; }
});
TB_Log(tbMsg, "func1 end, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
}
private async Task<int> func2()
{
TB_Log(tbMsg, "func2 start, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
await Task.Run(() =>
{
TB_Log(tbMsg, "func2 task.run, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
});
TB_Log(tbMsg, "func2 end, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
return 1;
}
And the code runs well, won't block. the code result shows:
click start, thread id:1
func1 start, thread id:1
click wait, thread id:1
func1 task.run, thread id:3
func2 start, thread id:3
func2 task.run, thread id:4
func2 end, thread id:4
func1 end, thread id:1
click end, thread id:1
The task.Result
deadlock will not occur.
My question is:
- Why task.Result won't cause a deadlock?
- Why func1 end, thread id is 1, not 4 or 3?
About the 2. question, I opened a Console project to replace the Winform project.
The result is a little different.
static async Task Main(string[] args)
{
Console.WriteLine("Main Start, thread id:" + Thread.CurrentThread.ManagedThreadId);
Task task = func1();
await task;
Console.WriteLine("Main End, thread id:" + Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
static private async Task func1()
{
Console.WriteLine("func1 start, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
await Task.Run(() =>
{
Console.WriteLine("func1 task.run, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
Task<int> task = func2();
if (task.Result == 5) {; }
});
Console.WriteLine("func1 end, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
}
static private async Task<int> func2()
{
Console.WriteLine("func2 start, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
await Task.Run(() =>
{
Console.WriteLine("func2 task.run, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
});
Console.WriteLine("func2 end, thread id:" + Thread.CurrentThread.ManagedThreadId.ToString());
return 1;
}
Main Start, thread id:1
func1 start, thread id:1
func1 task.run, thread id:4
func2 start, thread id:4
func2 task.run, thread id:5
func2 end, thread id:5
func1 end, thread id:4
Main End, thread id:4
The Main End id is not yet be 1.
Thanks you a lot. Because this is really confusing me.