I guess this kind of things should not be done in general, but I would like to understand why this code is getting the UI blocked, not returning from the await taskMain:
using System.Diagnostics;
namespace TasksTest
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void buttonTest1_Click(object sender, EventArgs e)
{
try
{
DoTest1Async().Wait();
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
private static async Task DoTest1Async()
{
Task taskMain = Task.Run(() => {
Debug.WriteLine("Test #1 completed");
});
await taskMain;
}
}
}
If instead of using Wait() I use await it works perfectly. I would like to know if there is a way of executing DoTest1Async synchronously without UI getting blocked.
------- EDITED ----------
Having understood that calling Wait method blocks the UI thread and doesn't allow the completed task taskMain to return to the UI thread context and resume execution... why this next code alternative does not block UI thread the same way??? I still don't understand why taskMain can return if I launch code in another thread having the UI thread blocked in the thread.Join but it can't return in a simple Wait() instruction. It sounds weird... Perhaps Wait method implementation needs a revision...?
private void buttonTest1_Click(object sender, EventArgs e)
{
Thread thread = new(() =>
{
try
{
DoTest1Async().Wait();
Debug.WriteLine("Unblocked!!");
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
});
thread.Start();
thread.Join();
Debug.WriteLine("Thread Finished!");
}
but I would like to understand why this code is getting the UI blocked
Because Task.Wait
is a blocking operation:
Wait is a synchronization method that causes the calling thread to wait until the current task has completed. If the current task has not started execution, the Wait method attempts to remove the task from the scheduler and execute it inline on the current thread. If it is unable to do that, or if the current task has already started execution, it blocks the calling thread until the task completes
not returning from the await taskMain
It returns, but the subsequent Wait
call blocks the thread.
If instead of using Wait() I use await it works perfectly.
If it works - use it, one of the reason of async
-await
introduction is to use in cases exactly like this.
I would like to know if there is a way of executing DoTest1Async synchronously without UI getting blocked.
No. By definition.
Also please read Don't Block on Async Code by Stephen Cleary. Blocking not only freezes UI thread but can lead to deadlocks (it seems that you are having one).