C# 在非UI线程中更新WritableBitmap.BackBuffer时,应用程序停止响应?

C# 在非UI线程中更新WritableBitmap.BackBuffer时,应用程序停止响应?,c#,wpf,multithreading,C#,Wpf,Multithreading,我需要异步更新图像的像素。我对本主题中建议的解决方案有问题-。因此,下面的代码是从非UI线程调用的。在执行此代码期间,应用程序停止响应: Dispatcher.Invoke(() => { _bitmap.Lock(); pBackBuffer =_bitmap.BackBuffer; }); unsafe { Marshal.Copy(_displayPixels, 0, pBackBuffer, _displayPixels.Length); } Dispatche

我需要异步更新图像的像素。我对本主题中建议的解决方案有问题-。因此,下面的代码是从非UI线程调用的。在执行此代码期间,应用程序停止响应:

Dispatcher.Invoke(() =>
{
_bitmap.Lock();
pBackBuffer =_bitmap.BackBuffer;
});

unsafe
{
    Marshal.Copy(_displayPixels, 0, pBackBuffer, _displayPixels.Length);   
} 

Dispatcher.Invoke(() =>
{
_bitmap.AddDirtyRect(new Int32Rect(0, 0, DepthWidth, DepthHeight));
_bitmap.Unlock();
});

我做错了什么?

停止货运。
不安全
块完全无用,请将其删除


这就是说,
\u bitmap.Lock()
\u bitmap.Unlock()
远不便宜。你对应用程序进行了分析吗?我很确定大部分时间都花在
Invoke
调用上,它确实在UI线程上运行。

尝试使用
Dispatcher.BeginInvoke
而不是
Dispatcher.Invoke
异步运行它。

这是个糟糕的主意。这需要同步运行才能正常工作,即使没有同步,也会在
BeginInvoke
期间阻塞GUI线程。问题不是阻塞非GUI线程,而是GUI线程有问题。感谢您的建议。探查器说,
PresentationFramework.dll
有42%的独占示例,但不是来自
\u bitmap.Lock()
。这不是热线电话。但如果这是真的。有什么办法不使用
Lock
?@CyberDreamer阅读profiler会产生这样的代码是很棘手的-它基本上告诉你42%的工作是在那些
Invoke
调用中进行的(可能不包括在代理内部花费的实际时间-很难说)。在某种程度上,没有其他选择-您正在复制完整的位图作为一个单一的操作;没有地方可以缩短执行时间。事实是,我根本不明白你为什么要触摸backbuffer——为什么不在你已经准备好位图的情况下,把它换成另一个位图呢?我想了想,然后做了下面的事情。在一个非UI线程中创建图像,并通过
调度程序在另一个非UI线程中更新图像。但是我遇到了
invalidoOperationException-调用线程无法访问此对象,因为在
\u bitmap.Unlock()
上有另一个线程拥有它。它是如何通过的?@CyberDreamer您只能在创建它的线程上使用它。也许你根本不想使用
WriteableBitmap
?哇,即使我不使用UI线程并通过Dispatcher调用
Lock/Unlock
,也行不通?我在哪里可以看到这些细节?对于
可写位图
,有什么替代方法?因此,我在UI线程中使用
\u bitmap.WritePixels
,而不在另一个线程中使用
锁定\解锁
和数据管理。这是工作!