问题描述
我有一个生成一系列的BitmapImage
对象的后台线程。每个后台线程完成生成位图的时候,我想显示此位图给用户。问题是搞清楚如何从后台线程通过的BitmapImage
到UI线程。
I have a background thread that generates a series of BitmapImage
objects. Each time the background thread finishes generating a bitmap, I would like to show this bitmap to the user. The problem is figuring out how to pass the BitmapImage
from the background thread to the UI thread.
这是一个MVVM的项目,所以我认为有一个图片
元素:
This is an MVVM project, so my view has an Image
element:
<Image Source="{Binding GeneratedImage}" />
我的视图模型有一个属性 GeneratedImage
:
private BitmapImage _generatedImage;
public BitmapImage GeneratedImage
{
get { return _generatedImage; }
set
{
if (value == _generatedImage) return;
_generatedImage= value;
RaisePropertyChanged("GeneratedImage");
}
}
我的视图模型还具有code创建后台线程:
My view-model also has the code that creates the background thread:
public void InitiateGenerateImages(List<Coordinate> coordinates)
{
ThreadStart generatorThreadStarter = delegate { GenerateImages(coordinates); };
var generatorThread = new Thread(generatorThreadStarter);
generatorThread.ApartmentState = ApartmentState.STA;
generatorThread.IsBackground = true;
generatorThread.Start();
}
private void GenerateImages(List<Coordinate> coordinates)
{
foreach (var coordinate in coordinates)
{
var backgroundThreadImage = GenerateImage(coordinate);
// I'm stuck here...how do I pass this to the UI thread?
}
}
我想以某种方式通过 backgroundThreadImage
到UI线程,在那里将成为 uiThreadImage
,然后设置 GeneratedImage = uiThreadImage
这样的观点可以更新。我看了一些例子对付WPF 调度
,但我似乎无法拿出解决此问题的一个例子。请指教。
I'd like to somehow pass backgroundThreadImage
to the UI thread, where it will become uiThreadImage
, then set GeneratedImage = uiThreadImage
so the view can update. I've looked at some examples dealing with the WPF Dispatcher
, but I can't seem to come up with an example that addresses this issue. Please advise.
推荐答案
下面使用调度到UI线程上执行的操作委托。这使用了同步模式,备用将异步执行委托。
The following uses the dispatcher to execute an Action delegate on the UI thread. This uses a synchronous model, the alternate Dispatcher.BeginInvoke will execute the delegate asynchronously.
var backgroundThreadImage = GenerateImage(coordinate);
GeneratedImage.Dispatcher.Invoke(
DispatcherPriority.Normal,
new Action(() =>
{
GeneratedImage = backgroundThreadImage;
}));
更新
正如在评论中讨论,因为的BitmapImage
未在UI线程上创建单独上面将无法工作。如果你没有修改图像的意向,一旦你已经创建了它,你可以使用冷冻它 Freezable.Freeze ,然后分配给GeneratedImage在调度委托(在BitmapImage的变,因此作为线程冻结的结果只读)。另一种选择是将图像加载到一个MemoryStream在后台线程,然后创建的BitmapImage在UI线程上与该流的BitmapImage的StreamSource的财产调度委托。
这篇关于你如何从后台线程在WPF UI线程传递的BitmapImage?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!