Featured post
c# - Timer in View Model -
i have service class in external assembly, inject class in view model class mef. need call service method every 3-4 seconds view model.
i service new data dictionary. dictionary bind listbox in view. , need refresh data listbox in view.
in solution use dispatchertimer, absolute begginer in calibur.micto mvvm , wpf. don’t know suitable solution in case. if have advance gratefull.
my solution here:
[export("mainscreen", typeof(imainviewmodel))] public class mainviewmodel : screen, imainviewmodel { [import] private service _service;//import mef external assembly [import] private connection _conn;//import mef external assembly //this dictionary bind listbox in view private myobservabledictionary<string, user> _users = null; //temp dictionry private myobservabledictionary<string, user> _freshusers = null; private int _selecteduserindex; private dispatchertimer _dispatchertimer; public account account{ get; set;} public int selectedusersindex { { return _selecteduserindex; } set { _selecteduserindex = value; notifyofpropertychange("selectedusersindex"); } } public mainviewmodel() { _dispatchertimer = new dispatchertimer(); _dispatchertimer.tick += dispatchertimer_tick; _dispatchertimer.interval = timespan.fromseconds(3); _dispatchertimer.start(); } //i every 3-4 sec server new json data , need update data listbox in view private void dispatchertimer_tick(object sender, eventargs eventargs) { //server ping, call service method account.ping = _service.ping(account); //refresh data in dictionary _freshusers = _service.loadusers(account); _users.clear(); selectedusersindex = 1; foreach (var freshuser in _freshusers) { _users.add(freshuser); } //check if have new messanges if (account.ping.rp > 0) { //load new messanges (int = 0; < account.ping.rp; i++) { #region load rp try { rp message = _service.loadrp(account); if (message != null) { //show messages } } catch (exception exception) { if (exception.message == "you haven’t messanged") { } throw exception;// how handle show exception in view? } #endregion } } } }
the dispatchertimer running on ui thread while running check ui freeze while dispatchertimer_tick message runs. if dispatchertimer_tick takes 2 seconds run every 3 seconds freeze ui 2 seconds. users won't that.
all service calls should done on non-ui thread don't lock ui i'd suggest using timer , doing this:
public mainviewmodel() { _sttimer = new system.threading.timer(timer_tick,null,3000,3000); _dispatcher = dispatcher.currentdispatcher; } private void timer_tick(object sender) { account.ping = _service.ping(account); //refresh data in dictionary _freshusers = _service.loadusers(account); _users.clear(); selectedusersindex = 1; foreach (var freshuser in _freshusers) { _users.add(freshuser); } for(int i=0;i<account.ping.rp; i++) { //check if have new messanges if (account.ping.rp > 0) { rp message = _service.loadrp(account); _messages.add(message); } } _dispatcher.begininvoke((action)(()=>{onpropertychanged("messages");})); }
here we're using system timer check changes on different thread, ui unaffected processing. when want notify ui change has occured can use _dispatcher (the ui dispatcher create in constructor) "begininvoke" method on ui thread.
this make app appear faster. rule of thumb keep off dispatcher thread as possible; use when you're doing ui. other processing should on background thread.
hope helps
- Get link
- X
- Other Apps
Comments
Post a Comment