c# - How to invoke an event asynchronously? -
i'm building control used other developers, , in few places have events developer can subscribe potentially long operations.
my goal give them option use async/await, multithreading, backgroundworkers etc. if choose, still able complete execution before event invocation completes. here's psuedo-code example (i realize doesn't compile, intention clear):
my code:
public event myeventhandler myevent; private void invokemyevent() { var args = new myeventargs(); // keep ui responsive until returns await myevent?.invoke(this, args); // show result messagebox.show(args.result); } developer's/subscriber's potential code:
// option 1: operation quick, // dev doesn't mind doing synchronously private void myform_myevent(object sender, myeventargs e) { // short operation, i'll right here. string result = doquickoperation(); e.result = result; } // option 2, operation long, // dev wants on thread , keep ui responsive. private void myform_myevent(object sender, myeventargs e) { myform.showprogresspanel(); // long operation, want multithread this! task.run(() => { string result = doverylongoperation(); e.result = result; }) .continuewith((task) => { myform.hideprogresspanel(); } } is there standard way accomplish this? looking @ delegate's begininvoke , endinvoke methods hoping help, didn't come anything.
any or advice appreciated! thanks!
there no standard way of doing this.
my personal preference, when in situation, use custom delegate type returning task. handlers return synchronously can return task.completedtask, don't need create new task this.
public delegate task myasynceventhandler(object sender, myeventargs e); public event myasynceventhandler myevent; private async task invokemyevent() { var args = new myeventargs(); // keep ui responsive until returns var myevent = myevent; if (myevent != null) await task.whenall(array.convertall( myevent.getinvocationlist(), e => ((myasynceventhandler)e).invoke(this, args))); // show result messagebox.show(args.result); } note capture of myevent in local variable avoid threading issues, , use of getinvocationlist() ensure tasks awaited.
note in implementation, if have multiple event handlers, scheduled @ once may execute in parallel. handlers need ensure not access args in thread-unsafe ways.
depending on use case, executing handlers sequentially (await in loop) more appropriate.
Comments
Post a Comment