我有两个IDisposables
我需要按顺序处理。从第一次开始,顺序就很重要IDisposable
终止依赖于将被第二个终止的服务的 Rx 订阅IDisposable
。这是在 Windows 窗体应用程序中,其中订阅IObservable
需要在不同的线程上进行,但观察和处理需要在 UI 线程上进行。 (实际上,只要确保顺序,我并不关心处理是否发生在 UI 线程上。)因此,在代码中我大致有以下内容(一旦减少):
SomeService = new DisposableService();
Subscription = Foo(someService).SubscribeOn(NewThreadScheduler.Default).ObserveOn(theForm).Subscribe(...)
对于许多 UI 事件,我需要按顺序处理这两个事件(订阅,然后是 SomeService)。为此,我尝试使用 RxCompositeDisposable
除了ContextDisposable
在同一线程上提供串行处理:
_Disposable = new CompositeDisposable(new[] {
new ContextDisposable(WindowsFormsSynchronizationContext.Current, Subscription),
new ContextDisposable(WindowsFormsSynchronizationContext.Current, SomeService)});
然而上面的方法不起作用。根据我的记录_Disposable
和ContextDisposable
for SomeService
在同一线程上调用,但ContextDisposable
仍然发生在与正在处理的服务同时发生的不同线程上(从而导致竞争条件和 NPE)。
我编写 C# 程序才几周时间,所以我确信问题出在我对上下文和调度程序如何工作的误解。解决这个问题的正确方法是什么?
除非我误解了什么,否则您可以控制哪个线程处理什么。谁订阅哪个线程并不重要。看这个例子
internal class Program
{
private static void Main(string[] args)
{
ReactiveTest rx1 = null;
ReactiveTest rx2 = null;
var thread1 = new Thread(() => rx1 = new ReactiveTest());
var thread2 = new Thread(() => rx2 = new ReactiveTest());
thread1.Start();
thread2.Start();
Thread.Sleep(TimeSpan.FromSeconds(1));
thread1.Join();
thread2.Join();
rx1.Dispose();
rx2.Dispose();
}
}
public class ReactiveTest : IDisposable
{
private IDisposable _timerObservable;
private object _lock = new object();
public ReactiveTest()
{
_timerObservable = Observable.Interval(TimeSpan.FromMilliseconds(250)).Subscribe(i =>
Console.WriteLine("[{0}] - {1}", Thread.CurrentThread.ManagedThreadId, i));
}
public void Dispose()
{
lock (_lock)
{
_timerObservable.Dispose();
Console.WriteLine("[{0}] - DISPOSING", Thread.CurrentThread.ManagedThreadId);
}
}
}
这输出
[14] - 0
[7] - 0
[15] - 1
[7] - 1
[14] - 2
[15] - 2
[10] - DISPOSING
[10] - DISPOSING
您可以看到我们在两个单独的线程上订阅,然后在第三个线程上处理。我只是锁定了处置,以防您在订阅中需要发生线程安全的事情。在这个例子中,这实际上是不必要的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)