WPF NotifyIcon From Background Thread -


i know 1 not supposed touch ui elements threads other ui thread, new wpf , wondering if current working implementation can improved.

i have application comprised solely of notification tray icon, , want update icon background thread.

here program.cs entry point:

static class program {     [stathread]     static void main()     {         application.enablevisualstyles();         application.setcompatibletextrenderingdefault(false);          using (iconhandler notify = new iconhandler())         {             notify.display();             application.run();         }      } } 

this iconhandler.cs notification icon handler class:

class iconhandler : idisposable {      notifyicon ni;      public iconhandler()     {         ni = new notifyicon();     }      public void display()     {         ni.mouseclick += new mouseeventhandler(ni_mouseclick);         ni.icon = resources.icon1;         ni.visible = true;          new thread(new threadstart(updateicon)).start();     }      public void updateicon()     {         while (true)         {             // reference ni directly, updates fine         }     }      public void dispose()     {         ni.dispose();     }      void ni_mouseclick(object sender, mouseeventargs e)     {         // useful     } } 

is there blatantly incorrect this? seems bit fishy me - first attempt. seems work want do, have suggestions better implementation? run lifecycle issues setup?

there blatantly incorrect this? seems bit fishy me - first attempt. seems work want do, have suggestions better implementation? run lifecycle issues setup?

to begin notifyicon not wpf control, comes windows forms namespace. such has normal c# properties (e.g. icon, visible) meaning have been able alter icon property in non-ui thread without exception being raised. if had used wpf controls have dependency properties , direct manipulation of dependency properties outside of ui thread cause exception raised.

run lifecycle issues setup?

you've not created wpf window or wpf controls. if application develops such start using wpf , updateicon method expanded more , access these wpf objects yes need strategy deal updates non-ui threads.

you can hide of cross-threaded access using helper methods.


example 1 if strategy becomes referencing wpf controls programmatically background thread can use helper method such this.

it first checks if call on ui thread, if updates control directly, otherwise schedule method (itself) called ui thread @ later point in time.

i've used begininvoke here background thread can continue before ui thread has called method. if want block background thread use invoke instead.

public void updatelabel(label control, string text) {    if (application.current.dispatcher.checkaccess())      control.content = text;   else     application.current.dispatcher.begininvoke(new system.action(() => updatelabel(control, text)), dispatcherpriority.normal); } 


example 2 if strategy uses events raised on background thread update wpf controls programmatically can hide of cross-threading calls part of raising event, leaving wpf update routine quite clean , simple read.

any event handlers of event can coded knowing call made ui thread, no threading issues.

public void onraiseevent(eventhandler handler, eventargs args) {   if (handler != null)     {     if (application.current.dispatcher.checkaccess())       handler(sender, new propertychangedeventargs(propname));     else       application.current.dispatcher.begininvoke(new system.action(() => handler(sender, args)), dispatcherpriority.normal);      } } 


example 3 if future strategy utilizes benefits of wpf binding (as opposed programmatically updating wpf controls), can embed cross-threading code data-bound objects.

if example xaml databinds myproperty property of instance of mydataclass class , class implements inotifypropertychanged interface can put cross-threading code in data class making possible update data thread. here example of class:-

public class mydataclass : inotifypropertychanged {     public event propertychangedeventhandler propertychanged;      private string _myproperty;      public string myproperty { { return _myproperty;} set { propertychanged.setvalueandnotify(this, ref _myproperty, value); } } } 

this class utilizes setvalueandnotify extension method on propertychanged event. in here hide cross-threading code simplify other parts of code. here's definition of extension method.

public static class propertychangedextension {     public static void setvalueandnotify<t>(this propertychangedeventhandler handler, object sender, ref t destination, t source, [callermembername] string propname = "notset")     {         // new value different previous value? if there no difference there nothing more         if (equals(destination, source))             return;          // if got point new value different old value, lets make assignemnt , raise property changed event         destination = source;          if (handler != null)         {             if (application.current.dispatcher.checkaccess())                 handler(sender, new propertychangedeventargs(propname));             else                 application.current.dispatcher.begininvoke(new system.action(() => handler(sender, new propertychangedeventargs(propname))), dispatcherpriority.normal);         }     } } 

the above example uses [callermembername] attribute c#5 remove typing errors in supplying property name inotifypropertychanged arguments. if not using latest need modify getter , setter follows:-

public string myproperty { { return _myproperty;} set { propertychanged.setvalueandnotify(this, ref _myproperty, value, "myproperty"); } } 

Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -