How to fix "marshalled for a different thread Error" on Async ProgressBar in UWP

0

I'm working on UWP Application which downloads images from the server asynchronously, Image downloading part works perfect and I am able to display thumbnails of the downloading image groups. My Problem is showing a progress bar as I download these images.

I know you need to use Dispatcher in order to avoid Thread Exception. and I am using it with no issues for displaying Thumbnail from Async Thread.

Heres my code. From "OnNavigatedTo" I call "RunTasksParallel()"

//start the progress bar

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

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

My Call Back Method looks like below, which is basically calling another method to populate Thumbnails.

 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. 
}

I have two methods which handle my progress bar activities.

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
        }

And

 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;

        }

when I run the application I get the following error "The application called an interface that was marshaled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))"

As you have noticed I just want to show a progress bar as Application is collecting images and those group header images (the first image received in a group) goes to list which binds to the grid. if I change progress bar to be IsIndeterminate with just start and stop. it does work.

c#
asynchronous
uwp
progress-bar
asked on Stack Overflow Apr 30, 2019 by Swapnil • edited Apr 30, 2019 by Derek Pollard

1 Answer

1

The application called an interface that was marshaled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))"

The problem is that you update or init the interface in the non-main thread. I checked the ProgressBarProgress and ProgressbarStart method, you have no need detect if main thread HasThreadAccess with recursive method. You could use main thread directly.

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;
   });
}
answered on Stack Overflow May 1, 2019 by Nico Zhu - MSFT

User contributions licensed under CC BY-SA 3.0