在UWP,MVVM中实施定期过程

时间:2018-10-07 20:08:26

标签: c# mvvm uwp scheduled-tasks

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

以下图片描述了我的应用程序。

enter image description here

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

现在,我想我可以说我想实现的目标。

如果我单击应用程序的“시작”按钮,我想每20秒执行一次Click功能。

幸运的是,我可以轻松地找到有关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(....),但这不是静态类,不能使用该语法。

我用Google搜索并尝试了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线程的种类……?)正在监视或保存该列表,因为我将其绑定到View页面。并且它返回异常“来自HRESULT的异常:0x8001010E(RPC_E_WRONG_THREAD)。”

如何在UWP中定期执行特定功能?

1 个答案:

答案 0 :(得分:1)

您需要使用应用程序的Dispatcher(与主窗口的调度程序匹配):

Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
        CoreDispatcherPriority.High,
        () =>
        {
            // UI components can be accessed within this scope.
            Click();
        });

您的方法不起作用的原因是无法从非UI线程调用Window.Current.Dispatcher,因为Window.Current仅可在UI线程上访问。但是Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher可以从任何地方访问。