task parallel library - Reactive Extensions subscribing to an observable (subject) -
i'm playing around reactive extensions first time in winforms application. mind have been doing web development past 4 years, , familiar observables , observable pattern in knockout, guessing contributing confusion here.
anyhow, question , code. have simple winforms experiment (see below) building illustrate question. subscribe below doesn't run until after thread in start new finished. can trace calls onnext, subscribe doesn't fire @ until 20-30 seconds later. can explain behavior me?
public partial class form1 : form { private subject<int> progress; private cancellationtoken cancellationtoken; private ischeduler _scheduler; public form1() { initializecomponent(); cancellationtokensource source = new cancellationtokensource(); cancellationtoken = source.token; _scheduler = new synchronizationcontextscheduler(synchronizationcontext.current); } private void start_click(object sender, eventargs e) { progress .observeon(_scheduler) //.throttle(timespan.fromseconds(5)) .subscribe( (i) => { progressbar1.do<progressbar>(ctl => { ctl.value = i; }); }, (ex) => { }, cancellationtoken ); task countertask = task.factory.startnew(() => { (var = 1; < 101; i++) { thread.sleep(500); progress.onnext(i); } }, cancellationtoken, taskcreationoptions.longrunning, taskscheduler.fromcurrentsynchronizationcontext() ); } private void form1_load(object sender, eventargs e) { progress = new subject<int>(); } } public static class controlextensions { public static void do<tcontrol>(this tcontrol control, action<tcontrol> action) tcontrol : control { if (control.invokerequired) control.invoke(action, control); else action(control); } }
your issue comes fact task running on ui thread, because you're using taskscheduler.fromcurrentsynchronizationcontext()
.
hence various sleep
calls blocking ui thread, freezing ui (e.g. can't drag window) , preventing observable subscription execute (because observeon
, it's supposed execute on ui thread scheduler).
replace taskscheduler.fromcurrentsynchronizationcontext()
taskscheduler.default
(background taskpool threads), , work expected.
note call do
/invoke
unnecessary, because you're on ui thread scheduler you've provided.
Comments
Post a Comment