WP8.1 C# Windows Phone 8.1 Background Task Writeab

2019-09-19 23:37发布

问题:

I am trying to update the band Me Tile image from a background task and i get the following error at WriteableBitmap:

System.Exception: The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
   at Windows.UI.Xaml.Media.Imaging.WriteableBitmap..ctor(Int32 pixelWidth, Int32 pixelHeight)
   at BackgroundTaskCS.UpdateBandTask.<LoadImage>d__f.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)

It looks like the WriteableBitmap needs to run on the UI Thread but I don't think I have access to UI thread since I need to update the tile without the app being open. Is there an alternative solution to this?

Below is the task I am using. Thanks in advance.

I started this question here and was directed to stackoverflow because of the band.

public async void Run(IBackgroundTaskInstance taskInstance)
        {
            BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();

             await UpdateMeTile();
            Debug.WriteLine("CS Task Run");

            _deferral.Complete();
        }

        private static async Task UpdateMeTile()
        {

            /// <summary>
            /// Connect to Microsoft Band and change the wallpaper.
            /// </summary>

            try
            {
                // Get the list of Microsoft Bands paired to the phone.
                IBandInfo[] pairedBands = await BandClientManager.Instance.GetBandsAsync();
                if (pairedBands.Length < 1)
                {
                    return;
                }

                // Connect to Microsoft Band.
                using (IBandClient bandClient = await BandClientManager.Instance.ConnectAsync(pairedBands[0]))
                {
                    // Change the wallpaper.
                    await bandClient.PersonalizationManager.SetMeTileImageAsync(await LoadImage("ms-appx:///Assets/SampleMeTileImage.jpg"));

                }

            }
            catch (Exception ex)
            {
                //this.textBlock.Text = ex.ToString();
                Debug.WriteLine("!!!!!!!!!!!!!!!!!!Exception. {0}", ex);
            }

        }


        private static async Task<BandImage> LoadImage(string uri)
        {
            StorageFile imageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri(uri));

            using (IRandomAccessStream fileStream = await imageFile.OpenAsync(FileAccessMode.Read))
            {

                WriteableBitmap bitmap = new WriteableBitmap(1, 1);
                await bitmap.SetSourceAsync(fileStream);
                bitmap.ToBandImage();
                return bitmap.ToBandImage();
            }
        }

回答1:

As mentioned by Rob Caplan in the original MSDN forum post, be sure to derive your background task from XamlRenderingBackgroundTask. Doing so will ensure that your background task's OnRun() method will be called on a "UI thread" (for the purposes of using UI-related types such as WriteableBitmap).