为什么 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);
    });
}