C# Application.Dispatcher和Window.Dispatcher之间的区别。。。?
让我介绍一下,我对WPF并不完全陌生,但今天我发现了一些我不知道它是如何工作的东西,我将简要介绍一下我所做的工作 我正在编写一个C#WPF代码,其中我需要根据某些条件填充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
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控件一样)。另外,自动分派是来自任何类型的绑定,我想不出一个没有自动分派的绑定。