2

WPFアプリケーションでは、オブジェクトを作成するBackgroundWorkerスレッドがありました。オブジェクトをfooと呼びましょう。

バックグラウンドワーカーコード:

SomeClass foo = new SomeClass();
// Do some operation on foo

// Set some dependency property on the main class to foo
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
    (SendOrPostCallback)delegate { SetValue(FooProperty, foo); },
    foo);

これで、メインクラスがゲッターを使用してFooPropertyにアクセスしようとすると、InvalidOperationExceptionが発生します。別のスレッドがオブジェクトを所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません。

オブジェクトの作成のスレッドが終了した場合、なぜそれがまだオブジェクトを所有しているのですか?どういうわけかこれの周りにありますか?

4

3 に答える 3

2

特定のスレッドで作成したオブジェクトは、そのスレッドによって所有されます。これが、InvalidOperationExceptionが発生する理由です。バックグラウンドスレッドでプロパティを設定する場合は、デリゲートに目的の値を返してもらい、メインスレッドからSetValueを呼び出すことをお勧めします。(オブジェクトを作成したスレッド)。

于 2009-10-30T17:32:50.593 に答える
1

WPFのオブジェクトの大部分は、スレッドアフィニティを持っています。これが特定のスレッドで作成されると、WPFオブジェクトはそのスレッドから使​​用された場合にのみ動作します。この制限は、(WinFormsとは異なり)そのオブジェクトに対して実行する実質的にすべての操作に適用されます。

このシナリオでは、実際のUIスレッドでFooを作成するようにコードを変更する必要があります。

于 2009-10-30T17:38:06.340 に答える
1

SomeClassから派生していると仮定するとDispatcherObject、それを作成したスレッドは、オブジェクトのメッセージの処理を担当するメッセージポンプを実行しfooます。したがって、そのスレッドが終了すると、オブジェクトはメッセージを処理できなくなります。これはお勧めできません。

ほとんどの場合、同じUIスレッドを使用して、すべてのUIオブジェクト(または、アプリケーションから派生しDispatcherObject、アプリケーションの期間中実行されることを確認するその他のもの)を作成する必要があります。次に、を使用しDispatcherて、ワーカースレッドからメッセージを送信します。

于 2009-10-30T17:43:13.723 に答える