【问题标题】:Using Async Task with Dispatcher to update UI thread in loop for WP8.1 WinRT from ViewModel使用带有 Dispatcher 的异步任务从 ViewModel 更新循环中的 WP8.1 WinRT 的 UI 线程
【发布时间】:2017-05-27 14:33:10
【问题描述】:

我是 Windows Phone Dev 的新手,正在将我的 WP8 SilverLight 应用程序迁移到 WP8.1 WinRT。以下是我在适用于 WP8 的 ViewModel 上的工作代码,但不适用于 Store 应用。

代码背后的逻辑是每秒更新 UI 线程上的 Xaml txtBox 值,这是在 UpdateTicker() 方法内完成的。

WP8 工作代码:

        Task.Run(async () =>
        {
            while (true)
            {
                await Task.Delay(1000);
                Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    UpdateTicker(); // this method gets called every second
                }), null);
            }
        });

在 MSDN 和 SO 上进行大量搜索后,我到了这里,下面的代码可以为 wp8.1 winRT 编译,但仍然无法正常工作 - 当设置断点时,调试器会到达 UpdateTicker()只执行一次,而 UpdateTicker 方法应该每秒调用一次,(这是第一个代码块发生的情况)

WP8.1 WinRT 代码:

        Task.Run(async delegate
        {
            while (true)
            {
                await Task.Delay(1000);
                CoreDispatcher dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
                await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    UpdateTicker();  // this method does not get called every second
                });
            }
        });

感谢任何有关从 ViewModel 为 wp8.1 env 一起使用 Async Task 和 Dispatcher.BeginInvoke(或类似)的指导。

【问题讨论】:

  • 你能定义“不起作用”是什么意思吗?
  • UpdateTicker() 不会像我在 wp8 env 下的第一个代码块中那样每秒被调用一次。
  • 我不熟悉 WinRT,但感觉就像在第二种情况下,您正在为后台线程获取调度程序。我想GetForCurrentThread 需要从 UI 线程中调用。 Task.Run 将导致从后台线程调用您的代码。我很可能是错的。
  • 这是 SO 上的另一个线程,link,他们努力实现我想要的,但这是来自后面的代码,我正在寻找有点相似但可以从 ViewModel 调用的线程。 ..
  • 我看到有人说将调度程序从UI线程传递到后台线程中运行的代码。我会试试的。

标签: c# multithreading windows-runtime async-await windows-phone-8.1


【解决方案1】:

其实我建议你避免Dispatcher、CoreDispatcher等。总有更好的解决方案。

在这种情况下,您可以使用进度更新。下面是一些适用于 Windows Phone Silverlight 8 和 Windows Phone Apps 8.1 的代码:

IProgress<object> progress = new Progress<object>(_ => UpdateTicker());
Task.Run(async () =>
{
  while (true)
  {
    await Task.Delay(1000);
    progress.Report(null);
  }
});

旁注:在生产代码中,您几乎从不想只启动 Task.Run 而不对返回的 Task 做任何事情。至少,您应该有一些代码(异步)等待从循环中捕获任何异常。

【讨论】:

  • 嘿,这个对我有用。实际上,我从未碰巧遇到过 IProgress 类。它们看起来很整洁。此外,我也会考虑您的建议和附注。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2022-10-18
相关资源
最近更新 更多