Как исправить ошибку "marshalled для другого потока" на Async ProgressBar в UWP - PullRequest
0 голосов
/ 30 апреля 2019

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

Я знаю, что вам нужно использовать Dispatcher, чтобы избежать исключения потоков. и я использую его без проблем для отображения миниатюр из Async Thread.

Вот мой код. Из «OnNavigatedTo» я вызываю «RunTasksParallel ()»

// запустить индикатор выполнения

public void RunTasksParallel()
        {
    ProgressbarStart(this.UserImageRepo != null ?     convert.ToInt32(this.UserImageRepo.Images):100);

   System.Threading.Tasks.Task.Run(() =>  this.UserImageRepo.GetUserImagesAsync(ImageReceived));
        }

Мой метод обратного вызова выглядит следующим образом, который в основном вызывает другой метод для заполнения миниатюр.

 bool ImageReceived(WriteableBitmap image, bool IsCompleted)
        {           
            if (IsCompleted)
            {
                imgloadprogress.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            }

            PopulateThumbnails(image);
            return true;
        }



 private async void PopulateThumbnails(WriteableBitmap image)
        {
            if (!Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.HasThreadAccess)
            {
               await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                () =>
                {
                    PopulateThumbnailImages(image);
                    return;
                    // Your UI update code goes here!
                });
            }
 ProgressBarProgress();
// Heres my code to populate the image list everytime the first group image goes different collection which has binding to datagrid. so I get all thumbnails.
// code to populate Image lists. 
}

У меня есть два метода, которые обрабатывают мои действия индикатора выполнения.

private async void ProgressbarStart(int Maximum)
        {
            if (!Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.HasThreadAccess)
            {
                await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                 () =>
                 {
                     ProgressbarStart(Maximum);
                     return;
                     // Your UI update code goes here!
                 });
            }

            imgloadprogress.Visibility = Windows.UI.Xaml.Visibility.Visible;
            imgloadprogress.Maximum = Maximum;
            imgloadprogress.Minimum = 0;
            imgloadprogress.Value = 0;
          //  imgloadprogress.val
        }

И

 private async void ProgressBarProgress()
        {
            if (!Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.HasThreadAccess)
            {
                await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                 () =>
                 {
                     ProgressBarProgress();
                     return;
                     // Your UI update code goes here!
                 });
            }


            if (imgloadprogress.Value + 1 > imgloadprogress.Maximum)
                imgloadprogress.Maximum = imgloadprogress.Maximum + 10;
            imgloadprogress.Value += 1;

        }

когда я запускаю приложение, я получаю следующую ошибку "Приложение вызвало интерфейс, который был маршалирован для другого потока. (Исключение из HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))"

Как вы заметили, я просто хочу показать индикатор выполнения, поскольку приложение собирает изображения, а те изображения заголовков группы (первое изображение, полученное в группе) попадают в список, который привязывается к сетке. если я изменю индикатор выполнения на IsIndeterminate с помощью только start и stop. это работает.

1 Ответ

1 голос
/ 01 мая 2019

Приложение вызвало интерфейс, который был маршалирован для другого потока. (Исключение из HRESULT: 0x8001010E (RPC_E_WRONG_THREAD)) "

Проблема в том, что вы обновляете или запускаете интерфейс в неосновном потоке. Я проверил метод ProgressBarProgress и ProgressbarStart, вам не нужно определять, является ли основной поток HasThreadAccess рекурсивным методом. Вы можете использовать основной поток напрямую.

private async void ProgressbarStart(int Maximum)
{
    await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
    () =>
    {
        imgloadprogress.Visibility = Windows.UI.Xaml.Visibility.Visible;
        imgloadprogress.Maximum = Maximum;
        imgloadprogress.Minimum = 0;
        imgloadprogress.Value = 0;
    });
}


private async void ProgressBarProgress()
{
    await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
   () =>
   {
       if (imgloadprogress.Value + 1 > imgloadprogress.Maximum)
           imgloadprogress.Maximum = imgloadprogress.Maximum + 10;
       imgloadprogress.Value += 1;
   });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...