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