如何告诉Di​​spatcher 已经初始化并且运行?

How to tell Dispatcher is initialized and running?

在我的控制台应用程序中,我一直在尝试启动 STA 线程并显示 WPF window。我已经成功地显示了 window,但是我在使用 Dispatcher(准确地说是 System.Reactive.Windows.Threading)的库中遇到了问题。我已经使用 this doc 中的代码解决了我的问题 - 我缺少的是在正确的时刻调用 System.Windows.Threading.Dispatcher.Run()

但是在仔细阅读这篇文章(和其他文章)并检查 Dispatcher's API 之后,我仍然不知道:如何判断 WPF Dispatcher 是否正确初始化和 运行宁?如果需要 Dispatcher 的图书馆可以检查它,这将非常有用。

-- 编辑--

// 在@Peter Duniho 评论后扩展我的问题

有了 C# 控制台应用程序,我想创建一个 WPF window,我将在其中观察 Dispatcher 上的一些数据。完整代码为here

所以我有我的程序,其中 Main class 看起来像这样:

static void Main(string[] args)
    {
        var observable = Observable
            .Interval(TimeSpan.FromMilliseconds(500))
            .TakeWhile(counter => counter < 10);

        var thread = new Thread(() =>
        {
            new TestWindow(observable);
            Dispatcher.Run();
        });

        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = true;
        thread.Start();

        Console.ReadKey();
    }

我在这里使用 Interval 运算符创建了一个可观察对象,它每 500 毫秒滴答一次,然后我将它传递给一个 TestWindow(下面的代码),我在一个单独的线程上 运行。在 10 个滴答声之后,我结束了可观察序列。

TestWindow class:

public class TestWindow : Window
    {
        public TestWindow(IObservable<long> observable)
        {
            var isDispatcherInitialized = false;

            Dispatcher.Invoke(() => isDispatcherInitialized = true, DispatcherPriority.ApplicationIdle);

            if (!isDispatcherInitialized)
                throw new ApplicationException("Dispatcher not initialized");

            observable
                .ObserveOnDispatcher()
                .Window(TimeSpan.FromMilliseconds(600))
                .Subscribe(_ => Console.WriteLine($"OnNext, observed on dispatcher with Window operator"));
        }
    }

在测试Window中,我在 Dispatcher (ObserveOnDispatcher()) 上观察我的可观察对象,并且我使用 Window 运算符。

该代码存在问题(在 .NET Framework 和 .NET Core 3.0 预览版上测试):

这就是为什么我想知道是否可以检测 Dispatcher 的状态。

如果您能详细说明此声明,将会很有帮助:

It'd be very useful for libraries requiring Dispatcher, if they could check it.

也就是说,它为什么会有用?

首先,如果您使用的是第三方库(例如您提到的 Reactive Extensions (Rx) for .NET,您怎么知道如何检查调度程序状态帮助该库?

另外,哪种情况不适合?缺乏要解决的具体问题,您的问题是相当开放的。目前尚不清楚哪种类型的答案会真正解决您的问题。

也就是说,我想到了两件事:

  1. 如果您想知道是否已为给定线程创建 调度程序,您应该调用System.Windows.Threading.Dispatcher.FromThread(System.Threading.Thread.CurrentThread); 这将return null 如果尚未为该线程创建调度程序,或者如果已经创建调度程序的引用。
  2. 如果你想知道调度器已经完成初始化并准备好调度东西,在我看来最简单的事情就是让它调度一些东西,当它调度时,它就准备好了。使用采用 DispatcherPriority 值的其中一种调用方法(BeginInvoke()Invoke()InvokeAsync())的重载,您可以获得有关级别的详细信息初始化已经发生。例如,如果您传递 DispatcherPriority.NormalDispatcherPriority.Send,当您的委托被调用时,您将知道调度程序是 运行。但是如果你传递 DispatcherPriority.ApplicationIdleDispatcherPriority.SystemIdle,你会知道不仅是调度程序 运行,而且它已经清除了要调度的初始事件的积压并且应用程序正在等待用户输入。