static void Main(string[] args)
{
Observable.Using(() => new EventLoopScheduler(), els => Observable
.Defer(() => Observable.Return(1))
.SubscribeOn(els))
.Subscribe();
Console.ReadLine();
}
为什么上面的代码会产生ObjectDisposedException? SubscribeOn究竟是如何运作的?
更多详情:
//can't compile
class DataService : ObservableBase<Unit>
{
protected override IDisposable SubscribeCore(IObserver<Unit> o)
{
return Observable.Defer(() => Observable.Start(() => _httpClient.Get(...)))
.RepeatWithDelay(TimeSpan.FromSeconds(1))
.ObserveOn(SchedulerEx.Current)//observe back to event loop
.Do(...)
.Select(_ => Unit.Default)
.Subscribe(o)
}
}
class Controller
{
void Start()
{
_instance = Observable.Using(
() => SchedulerEx.Create(),
els => _dataService.SubscribeOn(els));
}
void Stop()
{
_instance.Dispose();
}
}
class SchedulerEx
{
[ThreadStatic]
public static EventLoopScheduler Current;
public EventLoopScheduler Create()
{
var els = new EventLoopScheduler();
els.Schedule(() => SchedulerEx.Current = els);
return els;
}
}
static void Main()
{
var controller = kernel.Get<Controller>();
controller.Start();
controller.Stop();//throw if stop immediately
}
我想要实现的内容:在Windows服务应用程序中,我有多个DataService独立运行在他们自己的事件循环中,我可以回想一下当前的事件循环。
答案 0 :(得分:4)
这就是椒盐卷饼:
Observable.Using
与C#using
语句类似:它在观察结束后处置IDisposable
。 Observable.Defer
延迟运行包含的代码,直到订阅者订阅。 SubscribeOn
根据传入的IScheduler
指示observable应该订阅哪个线程。我测试了以下内容,它也爆炸了:
static void Main(string[] args)
{
Observable.Using(() => new EventLoopScheduler(), els =>
Observable.Empty<int>()
.SubscribeOn(els)
)
.Subscribe();
}
...所以Defer
没有影响。
显然Using
在调度程序被使用之前处置它。如果您将Observable.Empty
(或Observable.Return
)更改为未立即完成的内容(例如Observable.Never
或Observable.Interval(TimeSpan.FromMilliseconds(100)).Take(2)
,则不会将其炸毁。
它似乎是EventLoopScheduler
中的竞争条件错误:Observable.Using
和EventLoopScheduler
可能都试图调用Dispose
,如果错误的首先到达那里,爆炸。
我建议删除Using
。
答案 1 :(得分:1)
试试这个:
gradle-wrapper.properties
答案 2 :(得分:0)
Observable.Using(() => new EventLoopScheduler(),
els => new AnonymousObservable<long>(o => els.Schedule(Unit.Default, (_, s) => source.Subscribe(o))));
最后,我通过上面的代码解决了这个问题。
答案 3 :(得分:-1)
因为.Using()
而非常确定。在内部,它(最有可能)继续进行using () {}
构造,隐含地调用.Dispose()
。{/ p>