c# - How to wait for a return value from an event handler without blocking main UI thread -


so have method uses library generate external webpage allow user enter facebook credentials verification. upon entering creating profile based on user's account , saving database. once save database expecting boolean represent whether or not account unique. need way wait database complete of work before continuing execution.

i've tried several different methods including doing work on new thread (which won't work since ui needs on main thread) using autoresetevent wait auth.completed event fire. when using block thread , not present our external webpage user.

whats making more complicated trying deal different events without getting ahead of ourselves. first need wait auth.completed fire, inside event need wait asynchronous request.getresponseasync().continuewith<task<bool>>(async t => ... event finish, , wait database complete task , somehow push return value way calling procedure.

as of right now, code perform desired functions, return false since aren't waiting of events fire.

public bool loginfacebook(bool islinkedaccount)     { #if __ios__          uikit.uiwindow window = uikit.uiapplication.sharedapplication.keywindow;         uikit.uiviewcontroller viewcontroller = window.rootviewcontroller; #endif         var auth = new oauth2authenticator(                               clientid: "***********",                               scope: "email",                               authorizeurl: new uri("https://m.facebook.com/dialog/oauth/"),                               redirecturl: new uri("http://www.facebook.com/connect/login_success.html")                               );  #if __android__         forms.context.startactivity(auth.getui(android.app.application.context)); #elif __ios__         if (viewcontroller != null)         {             while (viewcontroller.presentedviewcontroller != null)                 viewcontroller = viewcontroller.presentedviewcontroller;             viewcontroller.presentviewcontroller(auth.getui(), true, null);         } #endif         // if authorization succeeds or canceled, .completed fired.         auth.allowcancel = true;         auth.completed += (sender, eventargs) =>         { #if __ios__             viewcontroller.dismissviewcontroller(true, null); #endif             if (eventargs.isauthenticated)             {                 var request = new oauth2request("get", new uri("https://graph.facebook.com/me"), null, eventargs.account);                 request.getresponseasync().continuewith<task<bool>>(async t =>                 {                     if (t.isfaulted)                         console.writeline("error: " + t.exception.innerexception.message);                     else                     {                         try                         {                             string content = t.result.getresponsetext();                             console.writeline(content);                             jobject user = jsonconvert.deserializeobject<jobject>(content);                             facebook profile = new facebook();                             profile.uuid = user["id"].tostring();                             profile.firstname = user["first_name"].tostring();                             profile.lastname = user["last_name"].tostring();                             profile.email = user["email"].tostring();                             profile.url = user["link"].tostring();                              //get picture                             profile.photo = "https://graph.facebook.com/" + profile.uuid + "/picture?type=large";                              if (!islinkedaccount)                             {                                 //app.animateloading(loadingimage, overlayimage, loadingmessage);                                 return await databaseinstance.insertsocialprofile(socialnetworks.facebook, profile, true);                             }                             else                             {                                 await databaseinstance.linksocialaccounttoprofile(app.userprofile, profile, socialnetworks.facebook);                                 return true;                             }                         }                         catch (exception e)                         {                             console.writeline(e.tostring());                         }                     }                     return false;                 });             }         };         return false;     } 

you can use taskcompletionsource represent awaitable task, negotiate between event handler , rest of async method.

for brevity , clarity, i've trimmed #ifdef code example, focusing on core. in mind, here's like:

public async bool loginfacebook(bool islinkedaccount) {     var auth = new oauth2authenticator(                           clientid: "***********",                           scope: "email",                           authorizeurl: new uri("https://m.facebook.com/dialog/oauth/"),                           redirecturl: new uri("http://www.facebook.com/connect/login_success.html")                           );      // if authorization succeeds or canceled, .completed fired.     auth.allowcancel = true;      taskcompletionsource<bool> completionsource = new taskcompletionsource<bool>();      auth.completed += (sender, eventargs) =>     {         completionsource.setresult(eventargs.isauthenticated);     };      if (!(await completionsource.task))     {         return false;     }      var request = new oauth2request("get", new uri("https://graph.facebook.com/me"), null, eventargs.account);     var t = await request.getresponseasync();      if (t.isfaulted)     {         console.writeline("error: " + t.exception.innerexception.message);         return false;     }      try     {         string content = t.result.getresponsetext();         console.writeline(content);         jobject user = jsonconvert.deserializeobject<jobject>(content);         facebook profile = new facebook();         profile.uuid = user["id"].tostring();         profile.firstname = user["first_name"].tostring();         profile.lastname = user["last_name"].tostring();         profile.email = user["email"].tostring();         profile.url = user["link"].tostring();          //get picture         profile.photo = "https://graph.facebook.com/" + profile.uuid + "/picture?type=large";          if (!islinkedaccount)         {             return await databaseinstance.insertsocialprofile(socialnetworks.facebook, profile, true);         }         else         {             await databaseinstance.linksocialaccounttoprofile(app.userprofile, profile, socialnetworks.facebook);             return true;         }     }     catch (exception e)     {         console.writeline(e.tostring());         return false;     } } 

naturally, change of method async method, caller can wait asynchronously on result, avoiding blocking of main thread.

of course, lacking a good, minimal, complete code example start with, above browser-edited code. did not compile it, never mind test it. above general idea. assume can incorporate concept in actual code.


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -