CでのInvokeの使用#---------マルチスレッド操作:スレッド間操作は無効であり、コントロールではないスレッドからアクセスされることはありません

インターフェイスをデザイン
し、ボタンをクリックした後にラベルの値を変更します。実現:ボタンをクリックしてボタンのクリックイベントを実行し、関数の下にスレッド変更を作成してから、このスレッドでラベルを変更するメソッドを実行しますChangeLabel();
ここに画像の説明を挿入
説明:コントロールはUIにありますメインスレッドで作成され、コントロールのイベント応答関数に入ると、メインスレッドではなく、コントロールのスレッドにあります。コントロールのイベント応答関数でコントロールの状態を変更すると、スレッドがメインスレッドと競合する可能性があります。
次の表現を直接使用すると、間違いを犯すことになります。

 private void btnChange_Click(object sender, EventArgs e)
 {
     Thread Change = new Thread(new ThreadStart(ChangeLabel));
     Change.Name = "zyh";
     Change.Start();
 }
 private void ChangeLabel()
 {
     try
     {
         label.Text = "改变值";
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message,"错误提示",MessageBoxButtons.YesNo,MessageBoxIcon.Error);
     }
 }

ここに画像の説明を挿入

解決策:

正しい方法は、コントロール応答関数でコントロールのInvokeメソッドを呼び出すことです。Invokeメソッドは、コントロールを作成したスレッド(通常はメインスレッド)が見つかるまでコントロールを検索し、そのスレッドに入ってコントロールの外観を変更し、スレッドの競合が発生しないようにします。正しい記述には3つの例があります。

最初の:

this.Invoke(new Action(()=>
{label.Text =“关闭”;}
));

第二種:

this.Invoke(new Action(
delegate {label.Text =“关闭”;}
));

3番目の種類:

コントロールのInvokeRequiredプロパティ値がtrueの場合、それは作成以外のスレッドがアクセスしたいことを意味します
。MSDNは
、コントロールへのメソッド呼び出しを行うときに呼び出し元がInvokeメソッドを呼び出す必要があるかどうかを示す値を取得しますサイドは、コントロールが作成されたスレッド以外のスレッドにあります。コントロールのハンドルが呼び出し側のスレッドとは別のスレッドで作成された場合(Invokeメソッドを介してコントロールを呼び出す必要があることを示す)の場合はtrue、それ以外の場合はfalse Windowsフォームのコントロールは特定のスレッドにバインドされており、スレッドセーフではありません。したがって、別のスレッドからコントロールメソッドを呼び出す場合は、コントロールのInvokeメソッドを使用して、適切なスレッドへの呼び出しをマーシャリングする必要があります。このプロパティを使用して、Invokeメソッドを呼び出す必要があるかどうかを判断できます。これは、コントロールを所有しているスレッドがわからない場合に役立ちます。

private void ChangeLabel()
{
try
{
    if (label.InvokeRequired)
    {
        label.Invoke(new MethodInvoker(ChangeLabel));
    }
    else
    {
        label.Text = "改变值";
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message,"错误提示",MessageBoxButtons.YesNo,MessageBoxIcon.Error);
}
}

プログラムの実行:
ボタンをクリックすると、システムはラベルスレッド以外のスレッドがアクセスしたいと判断します。このとき、InvokeRequired属性はtrueであり、Invokeメソッドを呼び出し、ChangeLabel()メソッドを実行し、elseにジャンプして、ラベルの変更を実行します。彼らは成功した。この時間は
ここに画像の説明を挿入
二つのスレッド、スレッドAとスレッドB、およびコントロールcが存在し、その中に新しいスレッドAさんが存在する場合、単純に、置きます。次に、スレッドAで実行されているc.InvokeRequiredというメソッドはfalseを返します。
逆に、スレッドBで実行されているメソッドがc.InvokeRequiredを呼び出すと、trueが返されます。
UIスレッドであるかどうかは、結果とは関係ありません。(スレッドは通常、コントロールUIスレッドですが、例外もある)
ここに画像の説明を挿入
参照ボーエン:
https://www.cnblogs.com/vaevvaev/p/6909042.html

元の記事を18件公開しました 賞賛されました0 訪問数233

おすすめ

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