在类库中获取UI调度程序

18

我想设计一个类库,并计划使用多线程(即 BackgroundWorker)。如果我打算将这些字段绑定到消费前端的库的GUI,那么我必须注意线程上下文,从中更新这些字段。根据我所读的,将GUI调度程序的引用传递给库不是一个好主意。但是我如何获得将使用该库的应用程序的调度程序?这是可能的吗?

我尝试过Application.Current.Dispatcher,并添加了对WindowBase的引用(因为我没有添加System.Windows的可能性),但仍然无法解析分派程序对象。

3个回答

28

Application类定义在PresentationFramework.dll中。为了能够通过Application.Current.Dispatcher访问调度程序,您需要引用该类库。


2
我同意使用 SynchronizationContext 是正确的做法。 - aqwert
1
我认为这不符合我的要求。我还不知道如何将这个想法转移到类库中 - 也许我漏掉了什么。 - rdoubleui
1
抱歉,我误解了问题。我已经更改了我的答案。 - John Leidegren
5
谢谢,这回答了我的问题。除了PresentationFrameworkWindowBase之外,我还需要引用System.Xaml - rdoubleui
那么我在哪里可以找到它呢?我在我的参考管理器中找不到它。 - Daan Luttik
@DaanLuttik 你是针对客户端配置文件还是旧版本的框架?这通常是您找不到程序集的原因。否则,它们肯定可以浏览,因为这里提到的所有内容都是框架的一部分。 - John Leidegren

8

我曾经遇到同样的问题,即无法解决Application.Current.Dispatcher,最终我将客户端GUI Dispatcher传递给库,该库仅持有Dispatcher引用(引用WindowsBase+使用System.Windows.Threading)。
与其让我的非GUI库携带对PresentationFramework.dll的引用(这似乎不自然),我更喜欢这个选项。
我想这两种方法各有优劣...


这是我以前做的方式,但似乎将调度程序引用传递到对象结构下面并不优雅。我可能错了。 - rdoubleui
1
我认为在类库中添加对PresentationFramework的引用并调用Dispatcher没有任何问题。这样,您就不需要任何额外的属性|变量|构造函数变量|额外注释,只需调用Dispatcher.Invoke(...) :D(如果最终不需要Dispatcher.Invoke(...),则删除PresentationFramework引用即可,非常简单 :p) - FocusedWolf

3

如果你确保(例如通过类的静态成员)有一个方便的UI Dispatcher的引用,你可以这样做:

public static void Run( Action a ) {
    if ( !_uiDispatcher.CheckAccess() ) {
        _uiDispatcher.BeginInvoke( a );
    }
    else {
        a();
    }
}

我看过的一两个MVVM框架会做这样的事情。

如果您不想将此 Dispatcher 引用传递给库,则可以使用IoC容器。 您还可以将其放入Common.dll中,以供exe和类库都需要引用的类和接口使用。 exe可以设置正确的引用,而类库可以调用 Run()方法。


2
我认为问题实际上是在库代码中获取UI/主线程调度程序。 - Ricibob
类似的问题,如果我理解正确的话,我可以将Dispatcher引用传递给类库,然后从那里在static上下文中使用它,这样我就可以在不向嵌套对象传递它的情况下访问它了?! - rdoubleui
1
确切地说,您将其保留在一个位置,其他所有内容都可以访问。如果多个库需要Common.dll,则我会提到它,尽管通常没有理由为此创建一个全新的库。它只需要放在其他所有内容引用的那个库中,以避免循环依赖。 - Joel B Fant
这是一种替代方法,谢谢。我将John Leidegren的声明标记为答案,因为它回答了我的原始问题。 - rdoubleui

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接