UWP中Dispatcher.RunAsync和ThreadPool.RunAsync之间的区别

时间:2018-05-14 09:12:06

标签: asynchronous canvas uwp dispatcher

我实现了一个基本的AutoSave方法,每当用户在UWP中的InkCanvas上绘制笔划时执行该方法。

我在此处遵循代码段https://docs.microsoft.com/en-us/windows/uwp/threading-async/submit-a-work-item-to-the-thread-pool,并使用Dispatcher.RunAsync另一种方法。我提出了3种方法,其中一种抛出了Marshall异常

方法1(抛出)(https://docs.microsoft.com/en-us/windows/uwp/threading-async/submit-a-work-item-to-the-thread-pool

    private void AutoSave()
    {
        IAsyncAction asyncAction
            = ThreadPool.RunAsync(
                async (workItem) =>
                {  
                  await ExportInk.SaveInkToLocalFileAsync(inkCanvas);
                });
        autoSaveWorkItem = asyncAction;

    }

方法2(https://docs.microsoft.com/en-us/windows/uwp/threading-async/submit-a-work-item-to-the-thread-pool

    private void AutoSave()
    {
        IAsyncAction asyncAction
            = ThreadPool.RunAsync(
                async (workItem) =>
                {
                    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
                        CoreDispatcherPriority.Normal,
                        new DispatchedHandler(async () =>
                        {
                            await ExportInk.SaveInkToLocalFileAsync(inkCanvas);
                        }));
                });
        autoSaveWorkItem = asyncAction;
    }

方法3(https://social.msdn.microsoft.com/Forums/en-US/d425e995-6822-4059-898f-0b5ff9586dfe/uwpcthe-application-called-an-interface-that-was-marshalled-for-a-different-thread-?forum=wpdevelop

    private async void AutoSave()
    {
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
          await ExportInk.SaveInkToLocalFileAsync(inkCanvas);
        });
    }

问题1 方法1是否因为我正在操作UI元素(InkCanvas)而抛出?

问题2 方法2和3有什么区别,为什么方法3似乎是方法?

提前感谢任何推荐

1 个答案:

答案 0 :(得分:0)

1 - 是的。应用程序中的每个窗口都有一个用于其UI的主线程,并且只有在此线程上才能操作UI元素。这可以通过该窗口的调度程序访问,该调度程序也从任何线程调度该窗口的UI线程的消息。

ThreadPool.RunAsync创建一个工作项来在一些任意ThreadPool线程上运行,这个线程可能通常不会成为你的UI线程。

由于您正在访问其某些UI属性的UI对象,因此您需要在UI线程上执行此操作。

2 - 对于方法2,你只是毫无意义地弹出一个线程池线程,只是为了告诉它回到UI线程去做它的工作。这是不必要的,因为没有任何工作要在该线程上完成,因为Dispatcher无论如何都要从UI线程发送它。 3避免这种情况 - 尽管如果已经从UI线程调用了自动保存,则甚至不需要调度程序调用。

您实际上在2&amp ;;上使用相同的Dispatcher 3如果你在一个窗口应用程序中,只是以不同的方式访问它。如果您的代码不在DependencyObject的代码隐藏中,那么您通过2访问的方式就是这样做。

有关Dispatcher的说明,请参阅https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.dependencyobject#remarks