.net - WPF 渲染线程失败异常
问题描述
在我的应用程序中,我有一个在后台运行的任务来执行一项长时间运行的工作。用户可以通过单击停止按钮随时取消作业。实现如下:
private CancellationTokenSource m_tokenSource;
private void onStop()
{
m_tokenSource.Cancel();
}
private void onStart()
{
m_tokenSource = new CancellationTokenSource();
AsyncDoingJob();
}
private async void AsyncDoingJob()
{
await Task.Run(() =>
{
for (int imgIdx = 0; imgIdx < m_ListImageFiles.Count; imgIdx++)
{
if (m_tokenSource.IsCancellationRequested) // Check if the user clicks Stop button
{
return;
}
byte[] imageData = File.ReadAllBytes(m_ListImageFiles[imgIdx]); // Load image in background
Application.Current.Dispatcher.Invoke(() =>
{
m_model.Image = CreateImage(imageData);
m_model.Image.Freeze();
MyImage = m_model.Image; // This calls NotifyPropertyChanged() to update the image on GUI
}
// Access to m_model.Image for some reason
}
}, m_tokenSource.Token);
}
问题:有时,在执行作业时,GUI 停止更新(挂起)。如果我尝试操作 GUI,则会发生异常: System.Runtime.InteropServices.COMException: UCEERR_RENDERTHREADFAILURE (Exception from HRESULT: 0x88980406)
我在这里发现了一个类似的问题: WPF render thread failures
你知道它是什么以及如何解决这个问题吗?我的源代码有什么问题吗?
解决方案
我不知道为什么你会得到这个错误。但是,您可以尝试这样的实现:
private bool continueLoading;
private void OnStop()
{
continueLoading = false;
}
private async Task OnStart()
{
continueLoading = true;
await LoadImagesAsync(m_ListImageFiles);
}
private async Task LoadImagesAsync(IEnumerable<string> imageFiles)
{
foreach (var imageFile in imageFiles)
{
if (!continueLoading)
{
break;
}
Image = await LoadImageAsync(imageFile); // assignment in UI thread
// do more async calls here if necessary
}
}
private static Task<ImageSource> LoadImageAsync(string fileName)
{
return Task.Run(() =>
{
using (var stream = File.OpenRead(fileName))
{
return LoadImage(stream);
}
});
}
private static ImageSource LoadImage(Stream stream)
{
return BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
// Alternative:
//
// var bitmapImage = new BitmapImage();
// bitmapImage.BeginInit();
// bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
// bitmapImage.StreamSource = stream;
// bitmapImage.EndInit();
// bitmapImage.Freeze();
// return bitmapImage;
}
推荐阅读
- javascript - 比较两个对象打字稿并检查是否有三个或更多值相同
- android - 平板电脑风景中的 BottomSheetDialogFragment
- node.js - 使用 MongoDB + NodeJS 生成唯一 ID 时处理竞争条件和饥饿
- python - Vignere Solver 和四边形适应度
- spring - Spring Webflux - R2dbc:如何在迭代结果集时运行子查询和更新值
- reactjs - 如何从大日历中获取选定的月份和年份
- kotlin - 如果类型参数由另一个类型参数限定,则类型参数不能有任何其他界限:这是什么意思以及如何解决它?
- javascript - Qualtrics:如何在随机发生器开始时隐藏下一个按钮
- postgresql - 如何在 Postgres 中完全禁用`client_min_messages`?
- postgresql - 可以使用 barman 设置 postgresql 流复制吗?