错误:即使使用Dispatcher,也必须在与DependencyObject相同的线程上创建DependencySou
本文关键字:DependencyObject DependencySou 创建 线程 Dispatcher 错误 | 更新日期: 2023-09-27 18:26:36
以下是我的View
的一部分,其中我已将图像绑定到ViewModel
中的属性:
<Image Source="{Binding Image}" Grid.Column="2" Grid.ColumnSpan="2"/>
我的ViewModel
是这样的:
public class MainWindowViewModel : INotifyPropertyChanged
{
public BitmapImage Image
{
get { return _image; }
set
{
_image = value;
OnPropertyChanged();
}
}
Action _makeScannerAlwaysOnAction;
private BitmapImage _image;
public MainWindowViewModel()
{
AddNewPersonCommand = new RelayCommand(OpenFrmAddNewPerson);
FingerPrintScannerDevice.FingerPrintScanner.Init();
MakeScannerAlwaysOn(null);
}
private void MakeScannerAlwaysOn(object obj)
{
_makeScannerAlwaysOnAction = MakeScannerOn;
_makeScannerAlwaysOnAction.BeginInvoke(Callback, null);
}
private void Callback(IAsyncResult ar)
{
FingerPrintScannerDevice.FingerPrintScanner.UnInit();
var objFingerPrintVerifier = new FingerPrintVerifier();
objFingerPrintVerifier.StartVerifingProcess();
var ms = new MemoryStream();
ms.Position = 0;
objFingerPrintVerifier.MatchPerson.Picture.Save(ms, ImageFormat.Png);
var bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
Thread.Sleep(2000);
Dispatcher.CurrentDispatcher.Invoke(() => Image = bi);
//Image = bi;
_makeScannerAlwaysOnAction.BeginInvoke(Callback, null);
}
private void MakeScannerOn()
{
while (true)
{
if (FingerPrintScannerDevice.FingerPrintScanner.ScannerManager.Scanners[0].IsFingerOn)
{
return;
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
我的问题:问题是当我想绑定图像时,它会给我错误
必须在与DependencyObject 相同的线程上创建DependencySource
我在谷歌上搜索了很多,我在SO中看到了这篇帖子,但它们都不适合我。
任何形式的帮助都将不胜感激。
BitmapImage
是DependencyObject
,所以在哪个线程上创建它并不重要,因为除非它是Freezable
对象,并且您可以Freeze
,否则您无法访问在另一个线程上创建的对象的DependencyProperty
。
使当前对象不可修改,并将其IsFrozen属性设置为true。
在更新Image
:之前,您需要调用Freeze
bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
bi.Freeze();
Dispatcher.CurrentDispatcher.Invoke(() => Image = bi);
正如@AwkwardCoder所指出的,这里是Freezable Objects Overview
虽然bi.Freeze();
在一个案例中对我有效,但我认为添加/删除没有什么区别
Dispatcher.CurrentDispatcher.Invoke(() => Image = bi);
第二次我在xaml中使用DataTemplate
,并且使用了与第一次相同的类,但我一直得到相同的Error。
这是一件有帮助的事情:
Application.Current.Dispatcher.Invoke(() => Image = bi);
也许可以改进已接受的答案,因为Dispatcher.CurrentDispatcher实际上并没有给您提供UI线程。