c# - Background Task sometimes able to update UI? -


i answered question whether task can update ui. played code, realized i'm not clear myself on few things.

if have windows form 1 control txthello on it, i'm able update ui task, seems, if on task.run:

public partial class form1 : form {     public form1()     {         initializecomponent();         task.run(() =>         {             txthello.text = "hello";         });     } } 

however if thread.sleep 5 milliseconds, expected crossthread error thrown:

public partial class form1 : form {     public form1()     {         initializecomponent();         task.run(() =>         {             thread.sleep(5);             txthello.text = "hello"; //kaboom         });     } } 

i'm not sure why happens. there sort of optimization extremely short running task?

you didn't post exception stack trace, expect looked this:

system.invalidoperationexception: cross-thread operation not valid: control 'textbox1' accessed thread other thread created on.    @ system.windows.forms.control.get_handle()    @ system.windows.forms.control.set_windowtext(string value)    @ system.windows.forms.textboxbase.set_windowtext(string value)    @ system.windows.forms.control.set_text(string value)    @ system.windows.forms.textboxbase.set_text(string value)    @ system.windows.forms.textbox.set_text(string value)    @ windowsformsapplicationcsharp2015.form1.<.ctor>b__0_0() in d:\test\windowsformsapplicationcsharp2015\form1.cs:line 27 

we can see exception thrown control.handle getter property. , in fact, if @ source code property, there is, expected:

public intptr handle {     {         if (checkforillegalcrossthreadcalls &&             !incrossthreadsafecall &&             invokerequired) {             throw new invalidoperationexception(sr.getstring(sr.illegalcrossthreadcall,                                                              name));         }          if (!ishandlecreated)         {             createhandle();         }          return handleinternal;     } } 

the interesting part when @ code calls control.handle. in case, that's control.windowtext setter property:

set {     if (value == null) value = "";     if (!windowtext.equals(value)) {         if (ishandlecreated) {             unsafenativemethods.setwindowtext(new handleref(window, handle), value);         }         else {             if (value.length == 0) {                 text = null;             }             else {                 text = value;             }         }     } } 

notice handle property invoked if ishandlecreated true.

and completeness, if @ code ishandlecreated see following:

public bool ishandlecreated {     { return window.handle != intptr.zero; } } 

so, reason don't exception, because time task executes, window handle hasn't been created yet, expected since task starts in form's constructor, is, before form displayed.

before window handle created, modifying property doesn't yet require work ui thread. during small time window @ start of program, seem possible invoke methods on control instances non-ui thread without getting "cross thread" exception. clearly, existence of special small time window doesn't change fact should make sure invoke control methods ui thread safe.

to prove point timing of window handle creation determining factor in getting (or not) "cross thread" exception, try modifying example force creation of window handle before start task, , notice how consistently expected exception, without sleep:

public partial class form1 : form {     public form1()     {         initializecomponent();          // force creation of window handle         var dummy = txthello.handle;          task.run(() =>         {             txthello.text = "hello"; // kaboom         });     } } 

relevant documentation: control.handle

if handle has not yet been created, referencing property force handle created.


Comments

Popular posts from this blog

yii2 - Yii 2 Running a Cron in the basic template -

asp.net - 'System.Web.HttpContext' does not contain a definition for 'GetOwinContext' Mystery -

mercurial graft feature, can it copy? -