C# ReactiveUI WPF-调用线程无法访问此对象,因为其他线程拥有它

C# ReactiveUI WPF-调用线程无法访问此对象,因为其他线程拥有它,c#,mvvm,reactive-programming,reactiveui,C#,Mvvm,Reactive Programming,Reactiveui,感谢@GlennWatson指出,除了ReactiveUI包之外,我还需要添加对Nuget包ReactiveUI.WPF的引用。 我有一个ReactiveObject视图模型,我想在其中使用OpenFileDialog设置一个视图模型属性(PdfFilePath)的值。 我尝试的所有操作都会导致调用线程无法访问此对象,因为该对象的所有者是另一个线程错误 我意识到下面的代码不符合MVVM,因为我使用的代码在视图模型中“显式引用/实例化视图的类型”,但我只是在寻找一个最小的示例,这样我就可以向后工作

感谢@GlennWatson指出,除了
ReactiveUI
包之外,我还需要添加对Nuget包
ReactiveUI.WPF
的引用。

我有一个
ReactiveObject
视图模型,我想在其中使用
OpenFileDialog
设置一个视图模型属性(
PdfFilePath
)的值。 我尝试的所有操作都会导致调用线程无法访问此对象,因为该对象的所有者是另一个线程错误

我意识到下面的代码不符合MVVM,因为我使用的代码在视图模型中“显式引用/实例化视图的类型”,但我只是在寻找一个最小的示例,这样我就可以向后工作,将视图和视图模型代码分开,并最终将服务传递给我的视图模型,该模型处理整个“选择文件路径”部分

public class ImportPdfViewModel : ReactiveObject
{
    public ImportPdfViewModel()
    {
        SelectFilePathCommand = ReactiveCommand.Create(() =>
        {
            OpenFileDialog ofd = new OpenFileDialog() { };
            //
            if (ofd.ShowDialog() == DialogResult.OK)
                PdfFilePath = ofd.FileName;
        });
    }

    private string _PdfFilePath;
    public string PdfFilePath
    {
        get => _PdfFilePath;
        set => this.RaiseAndSetIfChanged(ref _PdfFilePath, value);
    }

    public ReactiveCommand SelectFilePathCommand { get; set; }
}
正如我所提到的,我尝试了很多不同的选项,包括将服务注入到视图模型中,但是无论我在哪里实例化
OpenFileDialog
(例如在主视图中),我总是以相同的错误告终

我还用谷歌搜索了“ReactiveUI”和“OpenFileDialog”,但我发现的代码似乎都不是最新的(例如使用
ReactiveCommand
),也与任何其他示例不一致!谢谢


更新

感谢@GlennWatson指出,除了
ReactiveUI
包之外,我还需要添加对Nuget包
ReactiveUI.WPF
的引用。

我一添加它,代码就工作了

代码现在看起来是这样的,我认为它符合MVVM,使用依赖项注入,并使用了ReactiveUI的最新特性/最佳实践(尽管我很容易受到批评!):

ImportPdf

OpenFileDialogService


更新


我也有下面的错误造成的相同的丢失包
这种类型的CollectionView不支持从不同于Dispatcher线程的线程更改其SourceCollection。如果运行在WPF或WinForms平台上,则需要确保包含对ReactiveUI.WPF或ReactiveUI.WinForms的nuget引用。

通常,此类问题的解决方案是换行这会导致“Application.Current.Dispatcher.Invoke()”出现问题@RobinBennett感谢您的评论。。。然而,在我的Googleathon活动中,我看到了《ReactiveUI》的作者保罗·贝茨(Paul Betts)的评论(在文章的末尾),他说这不是正确的方式。我只是不知道如何推断他的实际答案(在那篇文章上面)来符合我的假设。另外,他的答案是从2013年开始的,我的印象是,ReactiveUI已经发生了足够大的变化,现在有了更好的方法。很公平——我应该提到我对ReactiveUI一无所知!:0)你不是唯一一个\0/!!你在哪个站台上跑步?如果没有包含正确的NuGet软件包,您经常会遇到线程问题。再次感谢格伦。我在问题的顶部强调了这一点,因为它似乎可以解决比我的
OpenFileDialog
问题多得多的问题0)
public class ImportPdfViewModel : ReactiveObject
{
    public ImportPdfViewModel(IIOService openFileDialogService)
    {
        SelectFilePathCommand = ReactiveCommand
            .Create(() => openFileDialogService.OpenFileDialog(@"C:\Default\Path\To\File"));
        SelectFilePathCommand.Subscribe((pdfFilePath) => { PdfFilePath = pdfFilePath; });
    }

    private string _PdfFilePath;
    public string PdfFilePath
    {
        get => _PdfFilePath;
        set => this.RaiseAndSetIfChanged(ref _PdfFilePath, value);
    }

    public ReactiveCommand<Unit, String> SelectFilePathCommand { get; set; }
}
public interface IIOService
{
    string OpenFileDialog(string defaultPath);
}
public class OpenFileDialogService : IIOService
{
    public string OpenFileDialog(string defaultPath)
    {
        OpenFileDialog ofd = new OpenFileDialog() { FileName = defaultPath };
        //
        if (ofd.ShowDialog() == DialogResult.OK)
        {
            return ofd.FileName;
        }
        else
        {
            return null;
        }
    }
}