c# - Modifying a list from another thread in WPF? -


i have wpf application mainwindow handling output of messages. i've set list of messages in window this:

public partial class mainwindow : window {     public concurrentbag<viewmessage> messagelist     {         { return (concurrentbag<viewmessage>)getvalue(messagelistproperty); }         set { setvalue(messagelistproperty, value); }     }      public static readonly dependencyproperty messagelistproperty = dependencyproperty.register("messagelist", typeof(concurrentbag<viewmessage>), typeof(mainwindow), new propertymetadata(null));      public mainwindow()     {         initializecomponent();     }      public void showmessage(string header, string message)     {         viewmessage message = new viewmessage("sucess", "example message");         messagelist.add(message);     } } 

the style of messages set fade out after time (3 seconds), , want remove item collection after time. don't know if it's possible in xaml only, if is, how do it?

i tried doing programatically this:

public mainwindow() {     timer timer = new timer();     timer.interval = 1000;     timer.elapsed += new elapsedeventhandler(messagechecktick);     timer.start();      //tried thread.start() }  private void messagechecktick(object sender, elapsedeventargs e) {     (int = messagelist.count - 1; >= 0; i++)     {         viewmessage message = null;         if (messagelist.trypeek(out message))         {             if (message.datemessage >= datetime.now.addmilliseconds(3000))             { messagelist.trytake(out message); }         }     } } 

but errors of the calling thread cannot access object because different thread owns it. tried solutions of similar questions in so, adding concurrentbag or using dispatcher, didn't work. in case of dispatcher can't call thread.sleep since it's main thread of program.

how can make work?

dispatchertimer great idea. write handler akin this:

// remove outdated var dtthreshold = datetime.now.addseconds(-3); foreach (var el in _localobservable.where(i => i.datemessage < dtthreshold).tolist())     _localobservable.remove(el);  // add new viewmessage message = null; while (messagelist.trytake(out message))         _localobservable.add(message); 

the observable collection must manipulated ui thread – therefore need keep concurrentbag (to add elements non-ui thread).

few things note:

  • .tolist() in remove section: ensures to-be-removed candidates determined before first of them removed (in case, enumeration of _localobservable ends before it's modified)

  • no need trypeek in advance - trytake take element , remove bag, giving element.

if don't use concurrentbag each add operation must posted ui thread. big number of add events may pollute ui thread, making slow & inefficient.


Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -