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

UIオブジェクトの操作は、UIオブジェクトを生成するスレッドで実行する必要があります

Formクラスにはブール型属性InvokeRequiredがあり、現在のスレッドがFormオブジェクト(UIスレッド)を作成したスレッドであるかどうかを確認するために使用できます。trueの場合、現在のスレッドはUIスレッドではないことを意味します。

TestFormで注意する必要がある2つのメソッドがあります。UIThreadはUIスレッドのシミュレーションに使用され、WorkerThreadはユーザースレッドのシミュレーションに使用され、メンバーform1およびform2はUIThreadでインスタンス化され、それらのShowメソッドが呼び出され、WorkerThreadで変更されます。 form1のTextプロパティ。
以下に示すコードを実行すると、次のウィンドウが正常に表示されます。
ここに画像の説明を挿入
プログラムの説明:
(1)メインウィンドウTestFormがスタートアップフォームで、次に2つの新しいインスタンスフォームform1およびform2
(2)コードform2.Show( );フォーム2を表示
(3)UIThreadスレッド(シミュレーションUIスレッド)で別のスレッドWorkerThreadメソッドが実行された場合、現在のスレッド(WorkerThread)はform2(UIThread)を作成したスレッドではなく、メソッドはInvokeメソッドを介して渡されますこれをUIスレッドに入れて実行します。このとき、InvokeRequiredの値はtrue(現在のスレッドがUIスレッドではないことを示します)です。Invokeメソッドを介してform1のテキスト属性を変更し、最後に3つのウィンドウを表示します

ただし、form2.Show()をコメント化すると、

エラー:スレッド間操作は無効であり、コントロールを作成したスレッドによってアクセスされることはありません

注:
form1とform2はどちらもUIThreadで作成されるため、それらが保持するスレッド情報は同じでなければなりません。したがって、form1.InvokeRquiredとform2.InvokeRquiredの値はどのスレッドでも同じです。つまり、WorkerThreadのInvokeRquireの値はtrueでなければなりません(別のスレッドで)、
ただしform2.Show()をコメントアウトすると、 form2のshowメソッドは、UIThreadスレッド(シミュレートされたUIスレッド)では使用されません。シミュレートされたユーザースレッドが実行されると、form2.InvokeRquiredはfalseになり、ユーザースレッドで直接操作されます(UIスレッドでform1の属性を変更します)。 Invokeメソッドは使用されないため、エラーが報告されます

ここに画像の説明を挿入

TestFormフォームコード

private Form form1;
private Form form2;      
public void UIThread()
{
    form1 = new Form();
    form2 = new Form();
    form2.Show();//注意这个地方!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    form2.Text = "form2";
    form1.Show();
    form1.Text = "form1";
    Thread thread = new Thread(new ThreadStart(WorkerThread));
    thread.Start();
}
//模拟用户线程,改变form1的text属性
public void WorkerThread()
{
    try
    {
        if (form2.InvokeRequired)
            form2.Invoke(new MethodInvoker(WorkerThread));
        else
            form1.Text = "This is from WorkerThread.";
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message,"错误提示");
    }
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    base.OnClosing(e);
    Application.Exit();

Program.csコード

 static void Main()
{
    TestForm tf = new TestForm();
    tf.Show();
    tf.UIThread();
    Application.Run();
}

参照ブログの投稿:
https : //blog.csdn.net/beelinkerlidejun/article/details/4772491

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

おすすめ

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