invokeメソッドを使用して、スレッド間アクセスの問題を解決する

C#では、コントロールへのスレッド間の直接アクセスは禁止されています。この問題を解決するためにInvokeRequiredが作成されます。コントロールのInvokeRequiredプロパティの値がtrueの場合、それを作成したスレッド以外のスレッドがコントロールにアクセスしたいと考えています。
コントロールが作成されたスレッド以外のスレッドに呼び出し元がいるため、コントロールへのメソッド呼び出しを行うときに、呼び出し元がInvokeメソッドを呼び出す必要があるかどうかを示す値を取得します。
別のスレッドからコントロールメソッドを呼び出す場合は、コントロールのInvokeメソッドを使用して、適切なスレッドへの呼び出しをマーシャリングする必要があります。

「button2」をクリックすると、別のスレッドbtn2によってラベル値が変更されますが、btn2スレッドは、invokeメソッドによって実行されます。このとき、button2のクリックイベントでスレッドが複数回呼び出されても、エラーは報告されません。エラーが発生し、ボタンがクリックされると、システムはそれがスレッド全体で呼び出されることを認識し、メソッドを実行するために呼び出しメソッド(委任)が使用され、問題はエラーなしで解決されます。
ブログ投稿を参照して
くださいhttps : //blog.csdn.net/qq_39217004/article/details / 105439971

 if (this.InvokeRequired)
 {
      this.Invoke(new dTest(test));
 }

public Form1()
{
    InitializeComponent();
}
private Thread btn1;
private Thread btn2;


// 模拟一个实际应用
// 对label1赋值后立马检查他的值,如果已经被改过则抛出异常 
void test()
{
    try
    {
        string strText = Guid.NewGuid().ToString();//随机生成一串字符
        this.label1.Text = strText;//改变label.Text的值
        if (this.label1.Text != strText)
        {
            MessageBox.Show("label1的值意外改变", "错误提示");
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "跨线程访问错误提示");
    }
}

// 使用invoke方法 
public delegate void dTest();
void invokeThread()
{
    for (int i = 0; i < 102; i++)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new dTest(test));
        }
        else
        {
            test();
        }
        Thread.Sleep(10);
    }
}
// 通过invoke方法,在主线程排队,lable1的值在test函数体内永远是线程安全的. 
private void button2_Click(object sender, EventArgs e)
{
    btn2 = new Thread(new ThreadStart(invokeThread));
    btn2.Name = "通过invoke方法";
    btn2.Start();
    btn2 = new Thread(new ThreadStart(invokeThread));
    btn2.Name = "通过invoke方法";
    btn2.Start();
} 
元の記事を18件公開しました 賞賛されました0 訪問数233

おすすめ

転載: blog.csdn.net/qq_39217004/article/details/105439971