C# 为什么代码会产生ObjectDisposedException
为什么上面的代码会产生ObjectDisposedException?SubscribeOn到底是如何工作的C# 为什么代码会产生ObjectDisposedException,c#,system.reactive,rx.net,C#,System.reactive,Rx.net,为什么上面的代码会产生ObjectDisposedException?SubscribeOn到底是如何工作的 更多详情: static void Main(string[] args) { Observable.Using(() => new EventLoopScheduler(), els => Observable .Defer(() => Observable.Return(1)) .SubscribeOn(el
更多详情:
static void Main(string[] args)
{
Observable.Using(() => new EventLoopScheduler(), els => Observable
.Defer(() => Observable.Return(1))
.SubscribeOn(els))
.Subscribe();
Console.ReadLine();
}
//无法编译
类数据服务:ObservableBase
{
受保护的覆盖IDisposable SubscribeCore(IObserver o)
{
返回Observable.Defer(()=>Observable.Start(()=>httpClient.Get(…))
.延时重复(时间跨度从秒(1))
.ObserveOn(SchedulerEx.Current)//观察返回事件循环
.Do(…)
.Select(=>Unit.Default)
.订阅(o)
}
}
类控制器
{
void Start()
{
_实例=可观察。使用(
()=>SchedulerEx.Create(),
els=>_dataService.SubscribeOn(els));
}
无效停止()
{
_Dispose();
}
}
类SchedulerEx
{
[线程静态]
公共静态事件调度程序当前;
public EventLoopScheduler Create()
{
var els=新的EventLoopScheduler();
els.Schedule(()=>SchedulerEx.Current=els);
返回els;
}
}
静态void Main()
{
var controller=kernel.Get();
controller.Start();
controller.Stop();//如果立即停止,则抛出
}
我想实现的是:在windows服务应用程序中,我有多个数据服务独立运行在它们自己的事件循环上,我可以在任何地方观察回当前事件循环。非常确定,因为
。Using()
。在内部,它(很可能)继续使用(){}构造,它在自身末尾隐式调用.Dispose()
。这就是椒盐卷饼:
Observable.Using
就像C#Using
语句:它在Observable结束后处理一个IDisposable
李>
可观察。延迟
延迟运行包含的代码,直到订户订阅李>
SubscribeOn
根据传入的isScheduler
指定应订阅可观察线程的线程
我测试了以下各项,它们也会爆炸:
//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
}
static void Main(字符串[]args)
{
可观察。使用(()=>new EventLoopScheduler(),els=>
可观察的。空的()
.SubscribeOn(els)
)
.Subscribe();
}
。。。因此,Defer
没有影响
显然,使用
是在使用调度程序之前对其进行处理。如果将Observable.Empty
(或Observable.Return
)更改为不能立即完成的内容(如Observable.Never
或Observable.Interval(TimeSpan.fromMillimes(100))。取(2)
,则不会爆炸
这看起来像是EventLoopScheduler
中的竞争条件错误:可能是可观察到的。使用和EventLoopScheduler
正在尝试调用Dispose
,如果错误的一个首先到达,则爆炸
我建议使用
Observable删除。使用(()=>neweventloopscheduler(),
static void Main(string[] args)
{
Observable.Using(() => new EventLoopScheduler(), els =>
Observable.Empty<int>()
.SubscribeOn(els)
)
.Subscribe();
}
els=>new-AnonymousObservable(o=>els.Schedule(Unit.Default,(u,s)=>source.Subscribe(o));
最后,我用上面的代码解决了这个问题。试试这个:
Observable.Using(() => new EventLoopScheduler(),
els => new AnonymousObservable<long>(o => els.Schedule(Unit.Default, (_, s) => source.Subscribe(o))));
可观察的。应该使用在延迟/返回可观察的处理之后处理EventLoopScheduler,对吗?可能是这样。至少,本机C#的使用()
正是如此。我还没有反编译源代码,但函数名基本上决定了它的行为……源代码就在这里:。没有使用
语句,因为可观察对象可以超出其范围。@Shlomo确实如此。因此,我的假设是错误的。霍华德,我不太相信:通过代码;它可能不包含using语句,但却以完全相同的方式运行。将using替换为最终会导致相同的结果。但我有点理解为什么会发生这种情况。就像有人看到他坐在树枝上一样。不,请不要使用此代码。有更简单的方法可以做到这一点。试试这个:Observable.Using(()=>new EventLoopScheduler(),els=>Observable.Defer(()=>Observable.Never().StartWith(1)).SubscribeOn(els)).Subscribe();
。这几乎完全是您的原始代码。发布的代码是一个最小的错误重现示例,因此实际上在Defer中有一个大服务。您所说的“Defer中的大服务”是什么意思?我正在编写一个windows服务。一个大的服务意味着整个应用程序的入口点在延迟中。你为什么试图将EventLoopScheduler
放在查询中?这似乎违背了使用此计划程序的目的。我正在尝试启动一个轮询服务,该服务假设在EventLoopScheduler上运行,当服务取消时,线程也应该结束。为什么它应该在EventLoopScheduler
上运行?
var els = new EventLoopScheduler();
var subscription =
Observable
.Return(1)
.Finally(() => els.Schedule(() => els.Dispose()))
.ObserveOn(els)
.Subscribe();
Console.ReadLine();