Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么代码会产生ObjectDisposedException_C#_System.reactive_Rx.net - Fatal编程技术网

C# 为什么代码会产生ObjectDisposedException

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

为什么上面的代码会产生ObjectDisposedException?SubscribeOn到底是如何工作的


更多详情:

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();