我正在构建一个从网站收集数据的小型应用程序。我设法收集了数据。
下图描述了我的应用程序的功能。
当我单击“시작”按钮时,我的应用程序会获取特定页面的 html,并从中获取数据。这项工作在 ViewModel 类中完成,我将结果数据绑定(bind)到 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; }
}
我绑定(bind)
data_list
数据到 viewPage
, GridView
.现在,我想我可以说出我想要实现的内容了。
如果我点击我的应用程序的“시작”按钮,我想每 20 秒执行一次点击功能。
幸运的是,我可以很容易地找到关于 UWP 中定期工作的文档。链接:create-a-periodic-work-item
因此,我尝试实现该功能,但失败了。
首先,我尝试了以下方法:
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()
函数调用 OnPropertyChanged()
来自 INotifyPropertyChanged
界面。但 Intellisense 告诉我,它找不到任何
Dispatcher
上下文中的名称。于是我直接右键点击重构菜单,然后,那句话就变成了
System.ServiceModel.Dispatcher.RunAsync...
但它不起作用。我找到了CoreDispatcher
文档中的类,所以我使用了它。我写了CoreDispatcher.RunAsync(....)
, 但它不是一个静态类,我不能使用那种语法。我用谷歌搜索并尝试了
Window.Current.Dispatcher.RunAsync(....)
但它返回异常“Windows.UI.Xaml.Windows.Current.get
返回 null
”。最后,我尝试了以下代码。
TimeSpan period = TimeSpan.FromSeconds(60);
ThreadPoolTimer PeriodicTimer = ThreadPoolTimer.CreatePeriodicTimer((source) =>
{
Click();
}, period);
但是程序在执行
Click
时崩溃了函数在 dataList 列表中添加元素,我认为其他线程(一种 UI 线程......?)在我将它绑定(bind)到查看页面时正在观看或持有该列表。它返回异常“来自 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# - 在 UWP、MVVM 中实现周期性进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52692433/