c# - Reactive Extensions - AsyncLock.Wait throws ArgumentNullException -
when using observable.interval
got few times following exception causes application crash (the exception can found in event viewer - error source: .net runtime)
application: rxplayground.exe framework version: v4.0.30319 description: process terminated due unhandled exception. exception info: system.argumentnullexception stack: @ system.reactive.concurrency.asynclock.wait(system.action) @ system.reactive.concurrency.defaultscheduler+<>c__displayclass9`1[[system.int64, mscorlib, version=4.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089]].<scheduleperiodic>b__6() @ system.reactive.concurrency.concurrencyabstractionlayerimpl+periodictimer.tick(system.object) @ system.threading.timerqueuetimer.callcallbackincontext(system.object) @ system.threading.executioncontext.runinternal(system.threading.executioncontext, system.threading.contextcallback, system.object, boolean) @ system.threading.executioncontext.run(system.threading.executioncontext, system.threading.contextcallback, system.object, boolean) @ system.threading.timerqueuetimer.callcallback() @ system.threading.timerqueuetimer.fire() @ system.threading.timerqueue.firenexttimers() @ system.threading.timerqueue.appdomaintimercallback()
have ever had such problems when using reactive extensions? know cause?
here code might caused issue (however maybe not because cannot reproduce it...):
static void main(string[] args) { var subscriptions = subscribetoobservables().take(10000).toarray(); console.writeline("begin. click enter dispose..."); console.readline(); console.writeline("disposing"); foreach (var subscription in subscriptions) { subscription.dispose(); } console.writeline("disposed. click enter finish..."); console.readline(); console.writeline("end"); } private static ienumerable<idisposable> subscribetoobservables() { var x = observable.interval(timespan.fromseconds(1)).select(n => { //thread.sleep(timespan.fromminutes(1)); return n; }); var sub = x.subscribe( n => { thread.sleep(timespan.fromminutes(1)); console.writeline(n); }); yield return sub; }
edit: have checked asynclock
class , references (https://github.com/reactive-extensions/rx.net/blob/master/rx.net/source/system.reactive.core/reactive/concurrency/asynclock.cs) , cannot see possibility action delegate ever null! in case of our exception can see stacktrace wait invoked following code (https://github.com/reactive-extensions/rx.net/blob/master/rx.net/source/system.reactive.core/reactive/concurrency/defaultscheduler.cs):
public idisposable scheduleperiodic<tstate>(tstate state, timespan period, func<tstate, tstate> action) { if (period < timespan.zero) throw new argumentoutofrangeexception("period"); if (action == null) throw new argumentnullexception("action"); var state1 = state; var gate = new asynclock(); var cancel = s_cal.startperiodictimer(() => { gate.wait(() => { state1 = action(state1); }); }, period); return disposable.create(() => { cancel.dispose(); gate.dispose(); action = stubs<tstate>.i; }); }
i have checked in il dasm system.reactive.concurrency.defaultscheduler+<>c__displayclass9`1[[system.__canon, mscorlib, version=4.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089]].b__6() compiled following lambda:
() => { gate.wait(() => { state1 = action(state1); }); }
it looks lambda () => { state1 = action(state1); }
passed null. but how possible?
it possible reproduce exception. have pass selector function, null. maybe forgot initialize in every case function in select block. or instance of class not existing anymore, when scheduler wants run it. way how possible:
func<long, int> selector = null; var x = observable.interval(timespan.fromseconds(1)).select(selector);
Comments
Post a Comment