Wpf child form, OnClosing event and await -


i have child form launched form parent form with:

configform cfg = new configform(); cfg.showdialog(); 

this child form used configure application parameters. want check if there changes not saved, , if so, warn user. on onclosing event declared way:

private async void childformclosing(object sender, system.componentmodel.canceleventargs e) {     // here call function compare current config saved config     bool isuptated = checkunsavedchanges();      // if updated false, means there unsaved changes...     if (!isupdated)     {          e.cancel = true;          // @ point create messagedialog (mahapps) warn user unsaved changes...         messagedialogstyle style = messagedialogstyle.affirmativeandnegative;          var metrodialogsettings = new metrodialogsettings()         {             affirmativebuttontext = "close",             negativebuttontext = "cancel"         };          var result = await this.showmessageasync("config", "there unsaved changes, want exit?", style, metrodialogsettings);          // if press close, want close child form , go parent...         if (result == messagedialogresult.affirmative)         {             e.cancel = false;         }     } } 

my logic says if declare e.cancel false continue closing form, doesn't happen, child form remains open.

my guess async call doing don't understand, because if declare childformclosing in way:

private async void childformclosing(object sender, system.componentmodel.canceleventargs e) {     bool isuptated = checkunsavedchanges();      e.cancel = true;      if (!isupdated)     {         messagedialogstyle style = messagedialogstyle.affirmativeandnegative;          var metrodialogsettings = new metrodialogsettings()         {             affirmativebuttontext = "close",             negativebuttontext = "cancel"         };          var result = await this.showmessageasync("config", "there unsaved changes, want exit?", style, metrodialogsettings);          if (result == messagedialogresult.affirmative)         {             e.cancel = false;         }     }     else     {         e.cancel = false;     } } 

the final else e.cancel = false works , child form closed...

any clue? thanks!

since method event handler window, called on ui thread already, there no need show message box asynchronously.

as strange behavior seeing, related await in event handler. when await method call, happening until await executed normal, once await statement reach control returns caller. once method awaited upon returns, rest of original method executes.

the code fires onclosing event not designed asynchronous event handlers in mind, assumes if event handler returns, has finished whatever work needs do. since event handler sets canceleventargs.cancel true before awaits on method call, caller event handler sees set true, doesn't close form.

this why showing message box synchronously works: entire method executed before control returns caller, canceleventargs.cancel set expected value.

raymond chen posted 2 articles async might interesting reading: crash course in async , await , the perils of async void. second article describes why async event handlers tend not work how expect them to.


Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -