programing

오류: Dispatcher를 사용하더라도 DependencyObject와 동일한 스레드에 DependencySource를 생성해야 합니다.

golfzon 2023. 4. 19. 23:45
반응형

오류: Dispatcher를 사용하더라도 DependencyObject와 동일한 스레드에 DependencySource를 생성해야 합니다.

다음은 저의 일부입니다.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에 있는 게시물을 보았지만 둘 다 저를 위해 일하지 않았습니다.

어떤 도움이라도 주시면 감사하겠습니다.

BitmapImageDependencyObject따라서 어떤 스레드로 작성되었는지는 중요하지 않습니다.왜냐하면 접속할 수 없기 때문입니다.DependencyProperty오브젝트가 아닌 한 다른 스레드에 생성된 오브젝트의 값을 지정합니다.

현재 개체를 수정할 수 없도록 설정하고 IsFrozen 속성을 true로 설정합니다.

당신이 해야 할 일은 전화하는 것이다.Freeze업데이트하기 전에Image:

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

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

@AwasmergeCoder가 지적한 바와 같이 여기 프리즈 가능한 오브젝트의 개요

하는 동안에bi.Freeze();한 가지 사례에서는 추가/삭제하는 것과 다를 바 없습니다.

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

두 번째로 사용했을 때DataTemplatexaml 및 첫 번째 경우와 동일한 클래스에서 동일한 오류가 계속 발생하였습니다.

이 점이 도움이 되었습니다.

Application.Current.Dispatcher.Invoke(() => Image = bi);

아마도 디스패처가 있기 때문에 인정된 답변이 개선될 수 있습니다.Current Dispatcher는 실제로 UI 스레드를 제공하지 않습니다.

언급URL : https://stackoverflow.com/questions/26361020/error-must-create-dependencysource-on-same-thread-as-the-dependencyobject-even

반응형