web-dev-qa-db-fra.com

Erreur: doit créer DependencySource sur le même thread que DependencyObject même en utilisant Dispatcher

Ce qui suit fait partie de mon View dans lequel j'ai lié une image à une propriété dans mon ViewModel:

<Image Source="{Binding Image}"  Grid.Column="2" Grid.ColumnSpan="2"/>

Mon ViewModel est le suivant:

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));
    }
}

Mon problème: Le problème est quand je veux lier l'image, cela me donne l'erreur

Doit créer DependencySource sur le même thread que DependencyObject

J'ai beaucoup cherché sur Google et j'ai vu le message dans SO mais aucun d'eux n'a fonctionné pour moi.

toute aide serait très appréciée.

24
Mehrdad Kamelzadeh

BitmapImage est DependencyObject donc peu importe sur quel thread il a été créé car vous ne pouvez pas accéder à DependencyProperty d'un objet créé sur un autre thread sauf s'il s'agit d'un Freezable objet et vous pouvez Freeze il.

Rend l'objet actuel non modifiable et définit sa propriété IsFrozen sur true.

Ce que vous devez faire est d'appeler Freeze avant de mettre à jour Image:

bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
bi.Freeze();

Dispatcher.CurrentDispatcher.Invoke(() => Image = bi);

comme l'a souligné @AwkwardCoder, voici Présentation des objets congelables

69
dkozl