WP8.1 C# Windows Phone 8.1后台任务WriteableBitmap线程错误
WP8.1 C# Windows Phone 8.1 Background Task WriteableBitmap Thread Error
我正在尝试从后台任务更新乐队 Me Tile 图像,但我在 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)
看起来 WriteableBitmap 需要 运行 在 UI 线程上,但我认为我无法访问 UI 线程,因为我需要在没有应用程序正在打开。对此有替代解决方案吗?
下面是我正在使用的任务。提前致谢。
我开始了这个问题 here 并且由于乐队的原因被引导到 Whosebug。
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();
}
}
正如 Rob Caplan 在原始 MSDN 论坛 post 中提到的那样,请务必从 XamlRenderingBackgroundTask 派生后台任务。这样做将确保您的后台任务的 OnRun() 方法将在 "UI thread" 上调用(为了使用 UI 相关类型,例如 WriteableBitmap)。
我正在尝试从后台任务更新乐队 Me Tile 图像,但我在 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)
看起来 WriteableBitmap 需要 运行 在 UI 线程上,但我认为我无法访问 UI 线程,因为我需要在没有应用程序正在打开。对此有替代解决方案吗?
下面是我正在使用的任务。提前致谢。
我开始了这个问题 here 并且由于乐队的原因被引导到 Whosebug。
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();
}
}
正如 Rob Caplan 在原始 MSDN 论坛 post 中提到的那样,请务必从 XamlRenderingBackgroundTask 派生后台任务。这样做将确保您的后台任务的 OnRun() 方法将在 "UI thread" 上调用(为了使用 UI 相关类型,例如 WriteableBitmap)。