C# 视图模型中的计时器

C# 视图模型中的计时器,c#,timer,viewmodel,caliburn.micro,C#,Timer,Viewmodel,Caliburn.micro,我在外部程序集中有服务类,我用MEF在视图模型类中注入这个类。我需要从视图模型每隔3-4秒调用服务方法 我从服务中获得新数据作为字典。此词典已绑定到视图中的列表框。我需要刷新视图中的数据列表框 在我的解决方案中,我使用Dispatchermer,但在calibur.micto中我是绝对的begginer,也使用MVVM和WPF。我不知道在我的情况下什么是合适的解决方案。因此,如果有人有预付款,我将不胜感激 我的解决方案是: [Export("MainScreen", typeof(IMainVi

我在外部程序集中有服务类,我用MEF在视图模型类中注入这个类。我需要从视图模型每隔3-4秒调用服务方法

我从服务中获得新数据作为字典。此词典已绑定到视图中的列表框。我需要刷新视图中的数据列表框

在我的解决方案中,我使用Dispatchermer,但在calibur.micto中我是绝对的begginer,也使用MVVM和WPF。我不知道在我的情况下什么是合适的解决方案。因此,如果有人有预付款,我将不胜感激

我的解决方案是:

[Export("MainScreen", typeof(IMainViewModel))]
    public class MainViewModel : Screen, IMainViewModel
    {

        [Import]
        private Service _service;//import with MEF from external assembly
        [Import]
        private Connection _conn;//import with MEF from external assembly

        //this dictionary is bind to the 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
        {
            get { return _selectedUserIndex; }
            set
            {
                _selectedUserIndex = value;
                NotifyOfPropertyChange("SelectedUsersIndex");
            }
        }



        public MainViewModel()
        {
            _dispatcherTimer = new DispatcherTimer();
            _dispatcherTimer.Tick += DispatcherTimer_Tick;
            _dispatcherTimer.Interval = TimeSpan.FromSeconds(3);
            _dispatcherTimer.Start();
        }


        //I get every 3-4 sec from server new JSON data and I need update  with this 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 you have new messanges
            if (Account.Ping.Rp > 0)
            {
                //load new messanges
                for (int i = 0; i < 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&#8217;t any messanged")
                        {

                        }
                        throw exception;// how handle show this exception in view?
                    }
                    #endregion
                }
            }
        }
    }
[导出(“主屏幕”,类型(IMainViewModel))]
公共类主视图模型:屏幕,IMainViewModel
{
[进口]
私有服务_Service;//使用MEF从外部程序集导入
[进口]
专用连接_conn;//使用MEF从外部程序集导入
//此词典已绑定到视图中的列表框
私有MyObservableDictionary _users=null;
//临时用语
私有MyObservableDictionary_freshUsers=null;
私有int _selectedUserIndex;
私人调度员;
公共帐户{get;set;}
公共int-SelectedUsersIndex
{
获取{return\u selectedUserIndex;}
设置
{
_selectedUserIndex=值;
财产变更通知(“选定的教育资源索引”);
}
}
公共主视图模型()
{
_Dispatchermer=新Dispatchermer();
_Dispatchermer.Tick+=Dispatchermer\u Tick;
_Dispatchermer.Interval=时间跨度(从秒开始)(3);
_dispatchermer.Start();
}
//我每隔3-4秒从服务器获取一次新的JSON数据,我需要更新视图中的数据列表框
私有void Dispatcher_Tick(对象发送方,EventArgs EventArgs)
{
//服务器ping,调用服务方法
Account.Ping=\u service.Ping(Account);
//刷新字典中的数据
_freshUsers=_service.LoadUsers(帐户);
_user.Clear();
SelectedUsersIndex=1;
foreach(var freshUser in_freshUsers)
{
_users.Add(freshUser);
}
//检查您是否有新消息
如果(Account.Ping.Rp>0)
{
//加载新消息范围
对于(int i=0;i
Dispatchermer正在您的UI线程上运行,因此当它运行检查时,您的UI可能会在运行Dispatchermer时冻结。如果Dispatchermer_勾选需要2秒才能运行,则每3秒冻结UI 2秒。用户不会喜欢这样

所有服务调用都应该在非UI线程上完成,这样就不会锁定UI,因此我建议使用计时器并执行以下操作:

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 you have new messanges 
       if (Account.Ping.Rp > 0) 
       { 
           Rp message = _service.LoadRp(Account); 
           _messages.Add(message);
       } 
    }

    _dispatcher.BeginInvoke((Action)(()=>{OnPropertyChanged("Messages");}));
}
public主视图模型()
{ 
_stTimer=新系统.Threading.Timer(Timer_Tick,null,30003000);
_dispatcher=dispatcher.CurrentDispatcher;
} 
私有无效计时器(对象发送器)
{
Account.Ping=\u service.Ping(Account);
//刷新字典中的数据
_freshUsers=_service.LoadUsers(帐户);
_user.Clear();
SelectedUsersIndex=1;
foreach(var freshUser in_freshUsers)
{ 
_users.Add(freshUser);
} 
对于(int i=0;i 0)
{ 
Rp message=\u service.LoadRp(帐户);
_消息。添加(消息);
} 
}
_dispatcher.BeginInvoke((操作)(()=>{OnPropertyChanged(“Messages”);});
}
在这里,我们使用一个系统计时器来检查不同线程上的更改,因此您的UI不会受到任何处理的影响。当我们想要通知UI发生了更改时,我们可以使用_dispatcher(我们在构造函数中创建的UI dispatcher)在UI线程上“BeginInvoke”一个方法

这将使你的应用程序显示得更快。一个很好的经验法则是尽可能远离Dispatcher线程;仅当您使用UI执行某些操作时才使用它。所有其他处理都应在后台线程上进行


希望这有帮助

很好。我在回答中使用了System.Threading.Timer部分,而不是使用_dispatcher,而是使用caliburn.micro的发布/订阅部分,为特定用例添加了一条新消息,然后称为IEventAggregator.PublishOnUIThread(…)。工作很愉快。谢谢