1

今日の仕事で困惑する状況に出くわしました。これを次のコードで簡略化しました。このコードはビルドされ、デバッグ中に例外をスローしません。

WinForms アプリがあるとします。私のメイン UI スレッドでは、オブジェクトをインスタンス化する別のスレッドをスピンオフし、そのオブジェクトがコントロールへの参照を保持します (私の例では label1)。次に、必要に応じてその実行を UI スレッドに戻すオブジェクト (SetLabelText) のメソッドを呼び出します。

私が困惑したのは、UI スレッドに戻って SetLabelText を実行したときに、Thing のインスタンスを作成しなかったスレッド (つまり、UI スレッド) で実行しているときに、.net CLR が labelText 変数にアクセスできる方法でした。

public partial class Form1 : Form
{
    delegate void DoSomethingDelegate();

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var t = new Thread(DoSomethingWithThing);
        t.Start();
    }

    private void DoSomethingWithThing()
    {
        var thing = new Thing(this.label1);
        thing.SetLabelText();
    }
}

public class Thing
{
    private Label label;
    private string labelText = "new value";
    delegate void SetLabelTextDelegate();

    public Thing(Label label)
    {
        this.label = label;
    }

    public void SetLabelText()
    {
        if (this.label.InvokeRequired)
        {
            var setLabelDel = new SetLabelTextDelegate(SetLabelText);
            this.label.Invoke(setLabelDel);
        }
        else
        {
            this.label.Text = this.labelText;
        }
    }
}
4

1 に答える 1