1

「detailschanged」というイベントを持つクラス「userdetails」があります。ユーザーの詳細が変更されるたびに発生します。
新しいフォームで「userdetails」(objUserDetails) の新しいオブジェクトを作成するとき、「detailschanged」イベントをサブスクライブして、データ変更についてユーザーに示します。

objUserDetails.detailschanged += InformtoUser

InformtoUser は新しい形式のメソッドです。InformtoUser メソッドでは、フォームのコントロール (ラベルのテキスト プロパティなど) にアクセスしています。
コントロールにアクセスすると、「クロス スレッド操作」エラーが発生します。
このクロススレッド操作を回避するには??

4

2 に答える 2

3

ここでの問題は、スレッド セーフです。

Windows フォーム コントロールへのアクセスは、本質的にスレッド セーフではありません。コントロールの状態を操作するスレッドが 2 つ以上ある場合、コントロールを強制的に矛盾した状態にすることができます。競合状態やデッドロックなど、その他のスレッド関連のバグが発生する可能性があります。コントロールへのアクセスがスレッドセーフな方法で実行されるようにすることが重要です。

Invoke メソッドを使用せずに、コントロールを作成したスレッド以外のスレッドからコントロールを呼び出すことは安全ではありません。

Control.InvokeWindows フォーム コントロールへのクロススレッド呼び出しを行うときに使用する必要があります。

例えば:

delegate void SetTextCallback(string text);

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

また:

this.Invoke((MethodInvoker) delegate {
    this.textBox.Text = "Some text here";
});

詳細については、「方法: Windows フォーム コントロールへのスレッド セーフな呼び出しを行う」を参照してください

于 2012-07-07T10:31:57.827 に答える
1

UI コントロールは、UI スレッドからのみ更新できます。WinForms を使用している場合は、次のことを行う必要があります。

mycontrol.Invoke((MethodInvoker)(() =>
{
  mycontrol.Text="some text";
}));

また、WPF を使用している場合は、ディスパッチャーを使用する必要があります。

myControl.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => myControl.Text = ""));
于 2012-07-07T10:32:36.180 に答える