c# - How to postpone execution until some event happens? -


i have webbrowser control , has invokescript method, should call after webbrowser loaded.

so i've tried this:

private readonly manualreseteventslim browserloaded = new manualreseteventslim(false);      private void browserloaded(object sender, navigationeventargs navigationeventargs) {                            browserloaded.set(); }  private async task<object> invokescript(string invoke, object[] parameters = null) {         return await task.factory             .startnew(() =>                       {                           if (!browserloaded.wait(timespan.fromseconds(10)))                           {                               throw new exception("timeout waiting browser load.");                           }                       })             .continuewith(task => parameters == null                 ? browser.invokescript(invoke)                 : browser.invokescript(invoke, parameters), taskscheduler.fromcurrentsynchronizationcontext()); }           

it not nice me, works ok when called asynchronously. problem appears, when try read result value synchronously - app hangs:

private string getenteredtext()  {      return (string)invokescript("getenteredtext").result; } 

i know, should go way async, i'm wondering properties:

public override string usertext {         {         return getenteredtext();     }     set     {         setenteredtext(value);     } } 

or async wrong way go in case @ all?

update

property 'glue' between input field value in browser's page , view model in wpf, don't see way make separate methods, because part of bigger framework (notice override keyword on it). once browser control loaded, execute logic should not take long, guess less 10 milliseconds, why ok sync execution in case. , browser control loads fast enough, reason here delay make sure invokescript not called before load, not because taking long time or smth.

app hangs

we'll, said yourself. know why happens. you're blocking on call using task.result, causes deadlock.

or async wrong way go in case @ all?

we don't have async properties. reason don't have them because properties aren't asynchronous nature. stephan cleary describes nicely:

if “property” needs asynchronously evaluated every time it’s accessed, you’re talking asynchronous operation.the best solution change property async method. semantically, shouldn’t property.

instead of property, make asynchronous method can await properly.

in regards using manualresetevent, use taskcompletionsource<bool> instead. works "nicer" tpl:

private taskcompletionsource<bool> tcs = new taskcompletionsource<bool>(); private void browserloaded(object sender, navigationeventargs navigationeventargs) {                        tcs.trysetresult(true); }  private async task<object> invokescript(string invoke, object[] parameters = null) {     var timeouttask = task.delay(timespan.fromseconds(10));     if (timeouttask == await task.whenany(tcs.task, timeouttask))     {         // you've timed out;     }      return task.run(() =>     {          parameters == null ? browser.invokescript(invoke)                             : browser.invokescript(invoke, parameters)     }); } 

i see used taskscheduler.fromcurrentsynchronizationcontext() in continuation. if need execute on ui thread, there no point in using threadpool thread @ all.

@noseratio adds webbrowser sta object. answer here might help.


Comments

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -