c# - WPF MVVM Multithreading Issue -


i've seen other issues similar mine, haven't seen can apply make code work.

so i'm new mvvm, , i'm trying stuff that's executing in background thread update on ui. i'm noticing first time bring ui, , background thread executes first time, if collection ienumerable<> ui isn't fully updated against backing data. if collection observablecollection<>, throws error.

from i've read, changes collections need executed on dispatcher thread, onpropertychanged() calls not. someone, please tell me how happening:

i'm altering _printers observable collection:

foreach (printerviewmodel pv in _printers)             {                 dispatcherexec(() =>                 {                 var abilities = x in _serverdata.types                                 select new printerability(                                     new printabletype() { id = x.id, name = x.name, numinprocunit = x.numinprocunit, printersmappedto = x.printersmappedto, sysname = x.sysname },                                     x.printersmappedto.contains(pv.printer.id)                                     );                       pv.printer.setabilities(abilities);                 }); 

my dispatcherexec looks so:

 private void dispatcherexec(action action)     {         //dispatcher.invoke((action)delegate          //{         //    action.begininvoke(null, null);          //}, null);         dispatcher.currentdispatcher.invoke((action)delegate         {             action.invoke();         }, null);     } 

and here's setabilities code fails:

 public void setabilities(ienumerable<printerability> abilities)     {         if (log.isinfoenabled)             log.info("setabilities(ienumerable<printerability> abilities): called on printer "+name);          list<printerability> l = new list<printerability>();         abilities.foreach(i =>             {                 i.printerabilitychanged += new printerabilitychangedeventhandler(onprinterabilitychanged);                 l.add(i);             }             );         lock (_abilities)         {             foreach (printerability pa in l)                 _abilities.add(pa);         }         if (log.isdebugenabled)             log.debug("setabilities(ienumerable<printerability> abilities): leaving");     } 

on _abilities.add(pa) observable collection add says "this type of collectionview not support changes sourcecollection thread different dispatcher thread." i'm thinking, "are joking?"

further, think change object in observable collection automatically make call oncollectionchanged(), right?

thanks in advance everyone.

using dispatcher.currentdispatcher not should bg thread. need use dispatcher dependencyobject-derived object has been created on ui thread.

also, you're iterating on *viewmodel objects (printerviewmodel) within bg thread. goes against mvvm. model should doing asynchronous stuff, , viewmodel(s) should handling asynchronous operations in way view can consume (by marshalling proper thread via dispatcher).

also, you're closing on loop variable (pv). bad, bad. (depending on order of execution) mean time dispatcher comes around, you'll multiple pv.printer.setabilities(...) calls on same printerviewmodel instance. create local variable inside loop , use within anonymous method avoid problem.


Comments

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -