Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Application.Dispatcher和Window.Dispatcher之间的区别。。。?_C#_.net_Wpf_Multithreading - Fatal编程技术网

C# Application.Dispatcher和Window.Dispatcher之间的区别。。。?

C# Application.Dispatcher和Window.Dispatcher之间的区别。。。?,c#,.net,wpf,multithreading,C#,.net,Wpf,Multithreading,让我介绍一下,我对WPF并不完全陌生,但今天我发现了一些我不知道它是如何工作的东西,我将简要介绍一下我所做的工作 我正在编写一个C#WPF代码,其中我需要根据某些条件填充ObservableCollection,并在UI中显示内容,因此在ViewModel中,我启动了一个BackgroundWorker线程 BackgroundWorker bgwRoot = new BackgroundWorker(); bgwRoot.DoWork += bgwRoot_DoWork(filepath

让我介绍一下,我对WPF并不完全陌生,但今天我发现了一些我不知道它是如何工作的东西,我将简要介绍一下我所做的工作

我正在编写一个C#WPF代码,其中我需要根据某些条件填充
ObservableCollection
,并在UI中显示内容,因此在
ViewModel
中,我启动了一个
BackgroundWorker
线程

 BackgroundWorker bgwRoot = new BackgroundWorker();
 bgwRoot.DoWork +=  bgwRoot_DoWork(filepath);
 bgwRoot.RunWorkerAsync();
 bgwRoot.RunWorkerCompleted += bgwRoot_RunWorkerCompleted;
线程将不断更新可观察的集合,当所有集合都完成时,BackgroundWorker将完成其工作

这里我想指出,
filecollections=newobservetecollection()
主线程中创建

因此,在
bgwRoot\u DoWork()
中,我无法直接更新
可观察集合。所以我用了
BeginInvoke

Application.Current.Dispatcher.BeginInvoke(new Action(() => this.FilesCollections.Add(myItem)));
但在调试时,我发现了这个应用程序。当前对象是
null
。最后,作为解决方案,我从codeBehind传递窗口对象,并解决了这个问题。 解决办法是

  • 创建窗口类的对象

    公共pUserControl用户控制

  • 并将其安装在视图模型中

    userControl=pUserControl

  • 最后

  • userControl.Dispatcher.BeginInvoke(新操作(()=>
    这个.FilesCollections.Add(myItem))

    所以我的问题是什么时候使用
    Application.Current.Dispatcher
    ? 在什么情况下,它实际上解决了线程问题?因为如果我在ViewModel中编写一个代码来更新任何
    集合
    ,并在UI中保留一个
    进度条
    ,那么VM对
    视图
    对象没有任何了解

    那么何时使用
    Application.Current.Dispatcher.beginInvoke()
    ?以及何时使用
    userControl.Dispatcher.BeginInvoke()


    请提供帮助。

    如果您的
    System.Windows.Application.Current
    为空,您将遇到严重问题。我建议你把它修好。也就是说,Application.Current.Dispatcher最有可能引用等于()Window.Dispatcher,这意味着它们几乎总是一样的。也就是说,我建议您忘记BackgroundWorker方法,改用async/await,这更干净。如果启动BGW太快,它将为null,在初始化应用程序对象之前。不清楚您是如何做到这一点的,可能您想使用Application.Startup事件。@HansPassant,或者可能存在其他问题,例如应用程序不是以
    System.Windows.Application
    启动的,而是一些自定义入口点,甚至是winforms应用程序,但是,是的,我会先检查一下什么时候运行。@DannyVarod不,它们不是线程安全的。这与单线程不同。只要您只有一个writer,它就可以来自任何线程(这种情况就是编写它的确切原因),它不需要与创建它的线程相同(就像大多数UI控件一样)。另外,自动分派是来自任何类型的绑定,我想不出一个没有自动分派的绑定。