C# do some work after all events are raised (or combine events) -
i'd subscribe event raised when of multiple other events raised.
suppose have multiple tasks (a
) first (for example animating multiple independent views), can subscribe event task complete, , i'd other work (b
) after of these events finished.
the amount of first tasks (a
) can differ each time, @ moment set counter number of tasks a
, subscribe n events, , in event handler task completion decrement counter, , when it's zero, task b.
is there nicer way combine these events using counter?
if understand question correctly, increment counter when start tasks , when each task completed, decrement counter in event handler. in event handler, check see (after decrementing counter) if counter zero. if so, task b.
i suggest @ tasks (aka "task parallel library (tpl)"), allows this:
task.whenall( new task[] { task.run(()=> { //... work a1... }, task.run(()=> { //... work a2... }, task.run(()=> { //... work a3... }}) .continuewith(()=> {//... work b... });
update: based on mention of wpf animations in comment below, task.run
may not fit here. if remember correctly, completed
event, , don't have way run animations synchronously in code (as in "...do work a1...").
however, instead of creating tasks via task.run
, can create them completed
event of storyboard
via extension method like:
public static task<storyboard> beginasync(this storyboard sb) { var tcs = new taskcompletionsource<storyboard>(); sb.completed += (s, a) => tcs.trysetresult(sb); sb.begin(); return tcs.task; }
note method creates task completed in storyboard's completed
event handler, , begins storyboard animation before returning task. note can write similar extension method other types , events.
you'd use method like, example:
var sb1 = (storyboard)mainwindow.findresource("storyboard1"); var sb2 = (storyboard)mainwindow.findresource("storyboard2"); var sb3 = (storyboard)mainwindow.findresource("storyboard3"); task.whenall( new task[] { sb1.beginasync(), sb2.beginasync(), sb3.beginasync() }) .continuewith(() => messagebox.show("all done!"), taskscheduler.fromcurrentsynchronizationcontext());
taskscheduler.fromcurrentsynchronizationcontext()
schedules continuation task run on ui thread (which required if accessing ui elements).
Comments
Post a Comment