c# - Batch updating UI component through observable collection with large amounts of data WinRT -


i have winrt application fires notifications everytime recieves data device. have ui control databound observable collection wish add new data to

while have made capable of updating observable collection, causes ui become laggy, amount of data generated fast. therefore better batch update, maybe every few hundred milliseconds.

below shows snippet of code. first create periodic timer

 timerelapsedhandler f = new timerelapsedhandler(batchupdate);         createperiodictimer(f, new timespan(0, 0, 3)); 

below event handler when new data comes in, along temporary list stores information

list<financialstuff> lst = new list<financialstuff>();     async void mydata_valuechanged(gattcharacteristic sender, gattvaluechangedeventargs args)     {         var data = new byte[args.characteristicvalue.length];         datareader.frombuffer(args.characteristicvalue).readbytes(data);         lst.add(new financialstuff() { time = "datetime.utcnow.tostring("mm:ss.ffffff")", amount = data[0] });      } 

then batch update, called peroidically

    private void batchupdate(threadpooltimer source)     {              additem<financialstuff>(financialstufflist, lst);                              } 

then finally, testing want clear observable collection , items.

    public async void additem<t>(observablecollection<t> oc, list<t> items)     {          lock (items)         {              if (dispatcher.hasthreadaccess)             {                 foreach (t item in items)                     oc.add(item);              }             else             {                 dispatcher.runasync(coredispatcherpriority.low, () =>                 {                      oc.clear();                     (int = 0; < items.count; i++)                     {                         items.count());                         oc.add(items[i]);                     }                     lst.clear();                  });             }         }      } 

while seems work, after few updates ui locks , updates slowly/if not @ all. testing, it's getting few hundred items in list time timer fired.

can enlighten me why why happening - i'm presuming design poor.

thanks

you're not locking list in event handler

// "lst" never locked in event handler list<financialstuff> lst = new list<financialstuff>(); lst.add(new financialstuff() { time = "datetime.utcnow.tostring("mm:ss.ffffff")", amount = data[0] }); 

passing "lst" above async method

additem<financialstuff>(financialstufflist, lst);     

you're locking "items" below, "lst" above. however, you're adding list while processing it. assume event handler has higher priority processing slower add. can lead "i < items.count" being true forever.

public async void additem<t>(observablecollection<t> oc, list<t> items) {     // "lst" reference locked here, wasn't locked in event handler      lock (items)     {         if (dispatcher.hasthreadaccess)         {             foreach (t item in items)                 oc.add(item);         }         else         {             dispatcher.runasync(coredispatcherpriority.low, () =>             {                 oc.clear();                  // may never exit loop                 (int = 0; < items.count; i++)                 {                     items.count());                     oc.add(items[i]);                 }                 lst.clear();             });         }     } } 

edit: need view every piece of data? there going overhead when using lock. if you're getting data quicker speed of how fast can render it, you'll backed and/or have large collection render, might cause problems. suggest filtering draw last x number of items (say 100). also, i'm not sure why need if (dispatcher.hasthreadaccess) condition either.

try following:

public async void additem<t>(observablecollection<t> oc, list<t> items) {     // "lst" reference locked here, wasn't locked in event handler      lock (items)     {         // change want         const int maxsize = 100;          // make sure doesn't index out of bounds         int startindex = math.max(0, items.count - maxsize);         int length = items.count - startindex;          list<t> itemstorender = items.getrange(startindex, length);          // can clear here in background thread.  references objects         // in itemstorender list.         lst.clear();          // dispatcher.runasync(coredispatcherpriority.low, () =>         // please verify correct syntax         dispatcher.run(() =>         {             // @ second look, might need locked             // edit: add overhead it's not running async.             // can remove lock             lock(oc)             {                 oc.clear();                  (int = 0; < itemstorender.count; i++)                 {                     // didn't notice before, why checking count again?                     // items.count());                     oc.add(itemstorender[i]);                 }              }         });     } } 

edit2: since additem method on background thread, don't think need run dispatcher.runasync. instead, think might desirable block don't end multiple calls section of code. try using dispatcher.run instead. i've updated code example above show changes. shouldn't need lock on oc anymore since lock on items enough. also, verify syntax dispatcher.run correct.


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

thorough guide for profiling racket code -