为什么 SynchronizationContext 如此重要
考虑这个例子:
private void button1_Click(object sender, EventArgs e)
{
label1.Text = RunTooLong();
}
此方法将冻结 UI 应用程序,直到 RunTooLong
完成。该应用程序将无响应。
你可以尝试异步运行内部代码:
private void button1_Click(object sender, EventArgs e)
{
Task.Run(() => label1.Text = RunTooLong());
}
但是这段代码不会执行,因为内部主体可能在非 UI 线程上运行,它不应该直接更改 UI 属性 :
private void button1_Click(object sender, EventArgs e)
{
Task.Run(() =>
{
var label1Text = RunTooLong();
if (label1.InvokeRequired)
lable1.BeginInvoke((Action) delegate() { label1.Text = label1Text; });
else
label1.Text = label1Text;
});
}
现在不要忘记总是使用这种模式。或者,试试 SynchronizationContext.Post
,它会为你做到:
private void button1_Click(object sender, EventArgs e)
{
Task.Run(() =>
{
var label1Text = RunTooLong();
SynchronizationContext.Current.Post((obj) =>
{
label1.Text = label1 Text);
}, null);
});
}