c# - 在 UWP、MVVM 中实现周期性进程
问题描述
我正在构建一个从网站收集数据的小型应用程序。我设法收集了数据。
下图描述了我的应用程序的功能。
当我单击“시작”按钮时,我的应用程序会获取特定页面的 html,并从中获取数据。这项工作在 ViewModel 类中完成,我将结果数据绑定到 ViewPage,观察我认为的 mvvm 模式。
以下源代码显示了我为程序编写的逻辑。
public class MainPageViewModel : Observable
{
public SiseDataList dataList { get; set; } = new SiseDataList();
public MainPageViewModel()
{
ButtonClick = new RelayCommand(Click);
}
public async void Click()
{
// ... omitted ..
foreach (var i in tmp_list)
{
if (dataList.Count == 0)
{
dataList.Add(i);
}
else if (dataList.Last().date < i.date)
{
dataList.Add(i);
}
}
OnPropertyChanged("data");
}
public RelayCommand ButtonClick { get; set; }
}
我将data_list
数据绑定到viewPage
, GridView
。
现在,我想我可以说出我想要实现的内容了。
如果我点击我的应用程序的“시작”按钮,我想每 20 秒执行一次点击功能。
幸运的是,我可以很容易地找到关于 UWP 中定期工作的文档。链接:创建定期工作项
因此,我尝试实现该功能,但失败了。
首先,我尝试了以下方法:
public MainPageViewModel()
{
ButtonClick = new RelayCommand(Regist);
}
public async void Regist()
{
TimeSpan period = TimeSpan.FromSeconds(60);
ThreadPoolTimer PeriodicTimer = ThreadPoolTimer.CreatePeriodicTimer(async (source) =>
{
Dispatcher.RunAsync(CoreDispatcherPriority.High,
() =>
{
// UI components can be accessed within this scope.
Click();
});
}, period);
}
public async void Click() //...omitted..
我把Click()
函数放在里面Dispatcher
,因为我认为函数是从接口Click()
调用的。但 Intellisense 告诉我,它在上下文中
找不到任何名称。
所以我只是右键单击它并单击重构菜单,然后,那句话变成了
但是它不起作用。我在文档中找到了类,所以我使用了它。我写了,但它不是一个静态类,我不能使用那种语法。 OnPropertyChanged()
INotifyPropertyChanged
Dispatcher
System.ServiceModel.Dispatcher.RunAsync...
CoreDispatcher
CoreDispatcher.RunAsync(....)
我用谷歌搜索并尝试过Window.Current.Dispatcher.RunAsync(....)
,但它返回异常“ Windows.UI.Xaml.Windows.Current.get
returns null
”。
最后,我尝试了以下代码。
TimeSpan period = TimeSpan.FromSeconds(60);
ThreadPoolTimer PeriodicTimer = ThreadPoolTimer.CreatePeriodicTimer((source) =>
{
Click();
}, period);
但是程序在执行Click
dataList 列表中的添加元素时崩溃了,我认为其他线程(一种 UI 线程......?)在我将它绑定到查看页面时正在观看或持有该列表。它返回异常“来自 HRESULT 的异常:0x8001010E (RPC_E_WRONG_THREAD)”。
如何在 UWP 中定期执行特定功能?
解决方案
您需要使用Dispatcher
应用程序(与主窗口的调度程序匹配):
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
CoreDispatcherPriority.High,
() =>
{
// UI components can be accessed within this scope.
Click();
});
您的方法不起作用的原因是无法Window.Current.Dispatcher
从非 UI 线程调用,因为Window.Current
只能在 UI 线程上访问。但是Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher
可以从任何地方访问。
推荐阅读
- c# - 实体框架:默认值问题
- java - 带有 Java 14 的 IntelliJ 2020.1 中的“记录”预览功能在 Maven“安装”期间因编译器错误而失败,但以其他方式运行
- r - 将 2 个 DF 匹配 2 列 R
- reactjs - 如何使用 React bootstrap typeahead 清除函数中的输入
- python - 如何动态地知道和实例化在 Python 模块中实现的一个类
- r - 在没有阿拉斯加和夏威夷的 R 中绘制美国地图
- c# - C#如何制作泛型方法
- python - Python list 按所需顺序重新排列元素
- node.js - Sequelize:如何在同一列的 WHERE 中使用 AND 运算符?
- javascript - 如何在脚本中更改 Google Docs 表格单元格中的文本颜色?