我想这种事情一般不应该做,但我想了解为什么这段代码会阻塞 UI,而不是从 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;
}
}
}
如果我不使用 Wait() 而使用 wait ,它会完美地工作。我想知道是否有一种方法可以同步执行 DoTest1Async 而不会阻塞 UI。
-----已编辑----------
了解调用 Wait 方法会阻塞 UI 线程,并且不允许已完成的任务 taskMain 返回到 UI 线程上下文并恢复执行...为什么下一个代码替代方案不会以同样的方式阻塞 UI 线程? ?我仍然不明白为什么如果我在另一个线程中启动代码而 UI 线程在 thread.Join 中被阻止,那么 taskMain 可以返回,但它不能在简单的 Wait() 指令中返回。听起来很奇怪...也许 Wait 方法的实现需要修改...?
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!");
}
但我想了解为什么这段代码会阻止 UI
Task.Wait
是一个阻塞操作:
Wait 是一种同步方法,它会导致调用线程等待,直到当前任务完成。如果当前任务尚未开始执行,Wait 方法会尝试从调度程序中删除该任务并在当前线程上内联执行它。如果它无法做到这一点,或者当前任务已经开始执行,它会阻塞调用线程,直到任务完成
未从等待任务Main返回
它返回,但后续的
Wait
调用会阻塞线程。
如果我不使用 Wait() 而使用 wait ,它会完美地工作。
如果它有效 - 使用它,
async
-await
介绍的原因之一就是在类似这样的情况下使用。
我想知道是否有一种方法可以同步执行DoTest1Async而不阻塞UI。
不。根据定义。
另请阅读 Stephen Cleary 的不要阻止异步代码。阻塞不仅会冻结 UI 线程,还会导致死锁(看来您遇到了死锁)。