c# - 在 UWP、MVVM 中实现周期性进程

标签 c# mvvm uwp scheduled-tasks

我正在构建一个从网站收集数据的小型应用程序。我设法收集了数据。

下图描述了我的应用程序的功能。

enter image description here

当我单击“시작”按钮时,我的应用程序会获取特定页面的 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/

相关文章:

c# - MVC 一种类型,一页 - 两种不同的 DisplayFor

c# - 系统和自定义命名空间之间的区别

c# - 如何覆盖基本 Controller 中 Json 辅助方法的行为

ios - RxSwift 格式文本

c# - 在 MVVM 中绑定(bind)的首选方法,资源文件中的数据模板或只是 View 本身中的 DataContext?

c# - 在 UWP 中创建/写入/压缩/解压缩文件

c# - 如何允许多种类型的部署?

wpf - 通过 MVVM 模式的动态 UI

c# - 将 UWP 应用程序中的 sqlite 数据库备份到一个驱动器

c# - 有什么正确的方法可以通过路径获取文件吗?