在我的应用程序中,我有PrimaryViewModel类(抽象),每个ViewModel都继承自它。 为了每隔X秒获取一次数据,我已经编写了以下虚拟方法
protected virtual async void RunSynchronizeTask()
{
await Task.Run(() =>
{
while (true)
{
Thread.Sleep(RefreshTime);
if (DateTime.Now.TimeOfDay - LastSyncrhonization.TimeOfDay > RefreshTime)
{
Application.Current.Dispatcher.Invoke(delegate
{
GetDataAndRefreshUI();
});
LastSyncrhonization = DateTime.Now;
}
}
});
}
因此,每个viewModel都有自己的方法和自己的任务,这些方法和任务将从数据库获取数据并刷新绑定的控件(例如messageViewModel每0.5秒刷新一次消息列表)
但是问题是,当我运行已发布的应用程序(无调试模式,仅作为发布版本并打开exe进行构建)并关闭时,该应用程序将关闭,但是此异步任务仍在工作(我在任务管理器中看到了该信息)>
我该怎么办? 如何将此任务分配给某事,我不能做: var task = await.Task.Run(...)
如果我可以创建一些引用这些任务的静态列表,并在应用程序关闭时将其杀死…………
答案 0 :(得分:3)
您从async void
转到Task.Run()
,这是原来的两倍。
然后,您可以在Dispatcher.Invoke()
这里唯一真正异步(并发)的是Thread.Sleep()
。
因此,您可以使用DispatcherTimer替换所有这些。那也应该解决您的停顿问题。
答案 1 :(得分:0)
感谢Fabian! 与取消令牌配合使用效果很好:
protected virtual async void RunSynchronizeTask()
{
var cancelationToken = new CancellationToken();
App.TaskToDisposeTokens.Add(cancelationToken);
await Task.Run(() =>
{
try {
while (true)
{
Thread.Sleep(RefreshTime);
if (DateTime.Now.TimeOfDay - LastSyncrhonization.TimeOfDay > RefreshTime)
{
Application.Current.Dispatcher.Invoke(delegate
{
GetDataAndRefreshUI();
});
LastSyncrhonization = DateTime.Now;
}
}
}
catch(OperationCanceledException) { }
}, cancelationToken);
}
App.Cs
private void Application_Exit(object sender, ExitEventArgs e)
{
foreach(var token in TaskToDisposeTokens)
{
token.ThrowIfCancellationRequested();
}
}
和App.Xaml
<Application x:Class="RandevouWpfClient.App"
...
Exit="Application_Exit">