Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.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
.net 确保在WPF中的UI线程上运行_.net_Wpf_Invoke_Dispatcher - Fatal编程技术网

.net 确保在WPF中的UI线程上运行

.net 确保在WPF中的UI线程上运行,.net,wpf,invoke,dispatcher,.net,Wpf,Invoke,Dispatcher,我正在构建一个WPF应用程序。我正在与服务器端进行一些异步通信,并在客户端使用带有Prism的事件聚合。这两种情况都会产生新的线程,而不是UI线程。如果我尝试在这些回调和事件处理程序线程上执行WPF操作,世界将会崩溃,现在已经开始这样做了 首先,我在尝试从服务器回调中创建一些WPF对象时遇到了问题。我被告知线程需要在STA模式下运行。现在我正在尝试更新Prism事件处理程序中的一些UI数据,我被告知: 调用方无法访问此线程,因为其他线程拥有它 所以,;在WPF中使事情正确的关键是什么?我已经读到

我正在构建一个WPF应用程序。我正在与服务器端进行一些异步通信,并在客户端使用带有Prism的事件聚合。这两种情况都会产生新的线程,而不是UI线程。如果我尝试在这些回调和事件处理程序线程上执行WPF操作,世界将会崩溃,现在已经开始这样做了

首先,我在尝试从服务器回调中创建一些WPF对象时遇到了问题。我被告知线程需要在STA模式下运行。现在我正在尝试更新Prism事件处理程序中的一些UI数据,我被告知:

调用方无法访问此线程,因为其他线程拥有它

所以,;在WPF中使事情正确的关键是什么?我已经读到了WPF调度员的资料。我开始明白了,但我还不是巫师

是始终使用Dispatcher.Invoke的关键,当我需要运行一些我不确定会在UI线程上调用的东西时,调用它? 如果它实际上是在UI线程上调用的,并且我执行Dispatcher.Invoke,这有关系吗? Dispatcher.Invoke=同步。Dispathcher.BeginInvoke=异步? 是否调用Dispatcher.Invoke请求UI线程,然后停止等待它?这是否是不良做法和响应性较差的项目的风险? 我怎么才能找到调度员?Dispatcher.CurrentDispatcher是否总是给我表示UI线程的Dispatcher? 是否会存在多个Dispatcher,或者Dispatcher与应用程序的UI线程基本相同? 那个幕后工作者怎么了?我什么时候用这个?我假设这总是异步的? 通过调用在UI线程上运行的所有内容都将在STA单元模式下运行吗?例如,如果我有需要在STA模式下运行的东西-Dispatcher.Invoke是否足够?
有人想帮我澄清一下吗?有什么相关的建议吗?谢谢

逐一检查您的每个问题:

不完全是,;您应该仅在必要时调用UI线程。见第2条。 是的,这很重要。您不应该只是自动调用所有内容。关键是仅在必要时调用UI线程。为此,可以使用以下方法。 这是正确的。 同样正确,是的,您确实面临响应性较差的程序的风险。大多数情况下,您不会看到严重的性能损失,我们所说的上下文切换的毫秒数,但您应该只在必要时调用。尽管如此,在某些情况下,这是不可避免的,所以不,我不会说这是一个坏习惯。这只是你偶尔会遇到的问题的一个解决方案。 在我所看到的每一个例子中,我都与Dispatcher.CurrentDispatcher进行了比较。对于复杂的场景,这可能还不够,但我个人还没有见过。 不完全正确,但这种思路不会有任何坏处。让我这样说:可以使用Dispatcher访问应用程序的UI线程。但它本身并不是UI线程。 BackgroundWorker通常在您有一个耗时的操作并且希望在后台运行该操作时维护一个响应良好的UI时使用。通常不使用BackgroundWorker而不是Invoke,而是将BackgroundWorker与Invoke结合使用。也就是说,如果需要更新BackgroundWorker中的某些UI对象,可以调用UI线程,执行更新,然后返回到原始操作。 对根据定义,WPF应用程序的UI线程必须在单线程单元中运行。
关于BackgroundWorker有很多要说的,我相信已经有很多问题专门讨论它了,所以我不会太深入。如果您有兴趣,请查看。

非常感谢Charlie!这是真正的澄清和帮助!在列表中添加了第八个问题。我希望你能更新你的答案,包括:-好答案+1,但我不同意你的部分答案2。调用Dispatcher.CheckAccess几乎总是一个坏主意。如果您想要发送优先级,只需使用它:Dispatcher.Invoke将识别它,并在可能的情况下进行直接调用。另一方面,如果您的任务优先级较低,您无论如何都不想调用CheckAccess。唯一的例外是,如果您想根据上下文改变任务的优先级。如果是这样,最好的方法是:Dispatcher.InvokeDispatcher.CheckAccess?DispatcherPriority.Send:DispatcherPriority.Render,…对5和6的另一个澄清:从概念上讲,每个线程都有自己的Dispatcher1-1关系。Dispatcher.CurrentDispatcher返回当前线程的调度程序。如果从UI线程调用,它将返回该线程的调度程序。如果从后台线程调用,它将返回后台线程的调度程序。应用程序可以有多个UI线程,因此访问DispatcherObject最安全的方法是通过其DispatcherObject.Dispatcher属性。但是 如果应用程序只有一个UI线程,则application.Current.Dispatcher将执行此操作。