Разница между Dispatcher.RunAsync и ThreadPool.RunAsync в UWP - PullRequest
0 голосов
/ 14 мая 2018

Я реализовал базовый метод автосохранения, который выполняется каждый раз, когда пользователь рисует обводку на InkCanvas в UWP.

Я следовал здесь фрагменту кода https://docs.microsoft.com/en-us/windows/uwp/threading-async/submit-a-work-item-to-the-thread-pool, а также другому подходу с использованием Dispatcher.RunAsync. Я придумал 3 метода, один из которых выдает исключение Маршалла

Метод 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 вызывает, потому что я манипулирую элементом пользовательского интерфейса (InkCanvas)?

Вопрос 2 В чем разница между методом 2 и 3 и почему метод 3 кажется подходящим?

Заранее спасибо за любую рекомендацию

1 Ответ

0 голосов
/ 14 мая 2018

1 - Да.Каждое окно в вашем приложении имеет один основной поток для своего пользовательского интерфейса, и только в этом потоке вы можете управлять элементами пользовательского интерфейса.Доступ к нему можно получить через диспетчер для этого окна, которое отправляет сообщения из любого потока, который также является потоком пользовательского интерфейса окна.

ThreadPool.RunAsync создает рабочий элемент для запуска в каком-либо произвольном потоке ThreadPool, который, вероятно, обычно никогда не выполняетсябыть вашим потоком пользовательского интерфейса.

Поскольку вы обращаетесь к объекту пользовательского интерфейса для некоторых его свойств пользовательского интерфейса, вам нужно быть в потоке пользовательского интерфейса, чтобы сделать это.

2 - Для метода 2 вашвы бессмысленно высовываетесь в поток пула потоков, просто чтобы сказать ему, что нужно вернуться к потоку пользовательского интерфейса, чтобы выполнить свою работу.В этом нет необходимости, поскольку никакая работа не будет выполнена в этом потоке, поскольку Dispatcher все равно отправляет все из потока пользовательского интерфейса.3 избегайте этого - хотя, если автосохранение уже вызывается из потока пользовательского интерфейса, нет необходимости в вызове Dispatcher.

Вы фактически используете тот же Dispatcher для 2 и 3, если находитесь в одном окнеприложение, просто разные способы доступа к нему.То, как вы получаете доступ через 2, - это то, что вы делали бы, если бы вашего кода не было в выделенном коде объекта DependencyObject.

См. https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.dependencyobject#remarks для заметок о Dispatcher

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...