C# 進行對 Windows Form 控制項的安全執行緒呼叫

Windows Form 控制項的存取並非原本就採用安全執行緒的方式。當有兩個或多個執行緒管理控制項的狀態,就有可能強制控制項進入不一致的狀態。其他與執行緒有關的錯誤也有可能如此,包括競爭情形和死結。

Un-Safety 的呼叫

private void setTextUnsafeBtn_Click(object sender, EventArgs e)
{
    this.demoThread = new Thread(new ThreadStart(this.ThreadProcUnsafe));

    this.demoThread.Start();
}

private void ThreadProcUnsafe()
{
    this.textBox1.Text = "This text was set unsafely.";
}

Safety的呼叫

private void setTextSafeBtn_Click(object sender, EventArgs e)
{
    this.demoThread = new Thread(new ThreadStart(this.ThreadProcSafe));

    this.demoThread.Start();
}

private void ThreadProcSafe()
{
    this.SetText("This text was set safely.");
}

delegate void SetTextCallback(string text);

private void SetText(string text)
{
    if (this.textBox1.InvokeRequired)
    {
        SetTextCallback d = new SetTextCallback(SetText);
        this.Invoke(d, new object[] { text });
    }
    else
    {
        this.textBox1.Text = text;
    }
}

使用BackgroundWorker元件進行Safety呼叫

private void setTextBackgroundWorkerBtn_Click(object sender, EventArgs e)
{
    this.backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    this.textBox1.Text = "This text was set safely by BackgroundWorker.";
}

為什麼不是把Threading設計成原本就是用安全執行緒的方式呢?