IDisposables
順番に処分する必要があるものが 2 つあります。IDisposable
最初の は、2 番目の によって強制終了されるサービスに依存している Rx サブスクリプションを強制終了するため、順序付けは重要IDisposable
です。これは、サブスクリプションのサブスクリプションが別のスレッドで発生する必要がある Windows フォーム アプリケーション内にありIObservable
ますが、監視と破棄は UI スレッドで発生する必要があります。(実際には、順序が保証されている限り、破棄が UI スレッドで発生するかどうかは気にしません。)したがって、コードでは、おおよそ次のようになります (一度縮小すると)。
SomeService = new DisposableService();
Subscription = Foo(someService).SubscribeOn(NewThreadScheduler.Default).ObserveOn(theForm).Subscribe(...)
多くの UI イベントでは、これらの両方を順番に破棄する必要があります (サブスクリプション、次に SomeService)。これを行うためにCompositeDisposable
、に加えて Rx を使用ContextDisposable
して、同じスレッドでシリアル処理を提供しようとしました。
_Disposable = new CompositeDisposable(new[] {
new ContextDisposable(WindowsFormsSynchronizationContext.Current, Subscription),
new ContextDisposable(WindowsFormsSynchronizationContext.Current, SomeService)});
ただし、上記は機能しません。私のロギングに基づいて_Disposable
、ContextDisposable
forSomeService
は同じスレッドで呼び出されますがContextDisposable
、サービスが破棄されると同時に別のスレッドでまだ発生しています (したがって、競合状態と NPE が発生します)。
私は C# をプログラミングしてまだ数週間しか経っていないので、問題はコンテキストとディスパッチャーがどのように機能するかについての私の誤解にあると確信しています。この問題に対する正しいアプローチは何ですか?