我有一个WritableBitmap,我想得到它的尺寸。因为该对象由另一个线程拥有,所以我们必须通过Dispatcher。我试过这个:
int targetPixelWidth = 0;
int targetPixelHeight = 0;
writeableBitmap.Dispatcher.Invoke(new Action(() =>
{
targetPixelWidth = writeableBitmap.PixelWidth;
targetPixelHeight = writeableBitmap.PixelHeight;
}));
// Do something with targetPixelWidth and targetPixelHeight
然而,这有时会失败:即使实际值不同,值也经常保持为0。
认为这可能是一个线程问题,我更改了代码如下:
var bitmapInfo = (Tuple<int, int>)writeableBitmap.Dispatcher.Invoke(new Func<Tuple<int, int>>(
() => Tuple.Create(writeableBitmap.PixelWidth, writeableBitmap.PixelHeight)
));
Debug.Assert(bitmapInfo != null, "Obviously, this should pass.");
targetPixelWidth = bitmapInfo.Item1;
targetPixelHeight = bitmapInfo.Item2;
// Do something with targetPixelWidth and targetPixelHeight
但是现在,bitmapInfo
有时是空的。这很奇怪,因为(根据文档)Invoke
应该只在委托没有返回值时返回null,这在这种情况下显然是这样。我甚至Debug.Assert
修改了Tuple.Create
的返回值,它永远不会为空。
我在这里缺少什么?导致这种竞争状况的原因,我该怎么办呢?
答案 0 :(得分:0)
修改强>
抱歉给出了错误的答案。似乎你想从另一个线程获取存在于gui线程中的WriteableBitmap的依赖属性。
你可以试试这个:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var writeableBitmap = new WriteableBitmap(100, 100, 300, 300, PixelFormats.Bgra32, null);
_image.Source = writeableBitmap;
new Thread(() =>
{
Thread.Sleep(1000);
var pixelHeigth = (Int32)writeableBitmap.Dispatcher.Invoke(
DispatcherPriority.Background,
(DispatcherOperationCallback)(arg => ((WriteableBitmap)arg).PixelHeight), writeableBitmap);
Debug.Print("PixelHeight:" + pixelHeigth);
}).Start();
}
我刚试过,效果很好。
答案 1 :(得分:0)
这有效,虽然我不知道为什么:
ManualResetEventSlim mre = new ManualResetEventSlim(false);
int targetPixelWidth = 0;
int targetPixelHeight = 0;
writeableBitmap.Dispatcher.Invoke(new Action(() =>
{
try {
targetPixelWidth = writeableBitmap.PixelWidth;
targetPixelHeight = writeableBitmap.PixelHeight;
}
finally {
mre.Set();
}
}));
mre.Wait();
// Do something with targetPixelWidth and targetPixelHeight
有人(发布了这个问题的答案,但后来删除了它),建议Invoke
在GUI线程上是同步的,而不是在调用Invoke
的线程上。如果这是真的,那就可以解释为什么会这样。但是,the documentation,图书[1,2]以及试图重现此问题的小玩具程序都表明情况并非如此; Invoke
应该在调用线程上同步。
我无法提出真正的解释;如果有人有,我全都耳朵:)。
编辑用更连贯的内容取代原来的,有点散漫的答案。