21

C# でデータをバインドすると、データを変更するスレッドによってコントロールも変更されます。ただし、このスレッドがコントロールが作成されたスレッドでない場合は、Illegal Cross Thread Operation 例外が発生します。

これを防ぐ方法はありますか?

4

4 に答える 4

5

次のようなことができるはずです。

if (control.InvokeRequired)
{
    control.Invoke(delegateWithMyCode);
}
else
{
    delegateWithMyCode();
}

InvokeRequired は、正しいスレッドにいるかどうかを確認するための Controls のプロパティです。Invoke は、正しいスレッドでデリゲートを呼び出します。

更新:実際、私の最後の仕事では、次のようなことをしました:

private void SomeEventHandler(Object someParam)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new SomeEventHandlerDelegate(SomeEventHandler), someParam);
    }

    // Regular handling code
}

これにより、else ブロックが不要になり、コードが強化されます。

于 2008-08-05T07:51:54.727 に答える
2

テスト ケースがないため、この解決策を保証することはできませんが、別のスレッドでプログレス バーを更新する (デリゲートを使用する) のと同様のシナリオが適していると思われます。

public delegate void DataBindDelegate();
public DataBindDelegate BindData = new DataBindDelegate(DoDataBind);

public void DoDataBind()
{
    DataBind();
}

データ バインディングを特定のスレッドで行う必要がある場合は、そのスレッドに任せてください。

于 2008-08-05T07:56:53.140 に答える
0

スレッド呼び出しが「不正」である場合 (つまり、DataBind 呼び出しが、呼び出し元のスレッドで作成されていないコントロールに影響を与える場合)、デリゲートを作成して、DataBind の決定/準備が行われない場合でも、デリゲートを作成する必要があります。コントロールを作成するスレッド、それらの結果の変更 (つまり、DataBind()) が行われます。

次のように、ワーカー スレッドから私のコードを呼び出します。

this.BindData.Invoke();

これにより、元のスレッドがバインディングを実行し、(コントロールを作成したスレッドであると仮定して) 動作するはずです。

于 2008-08-05T08:06:42.840 に答える
0

WPF と Silverlight では、バインディング インフラストラクチャが UI スレッドへの切り替えを処理します。

于 2008-08-08T16:19:17.923 に答える