在WinForms Classic Desktop应用程序中获取CoreDispatcher

时间:2018-04-27 23:02:29

标签: c# winforms dispatcher

我有一个C#WinForms应用程序,可以在后台线程上扫描蓝牙设备。当需要连接到设备时,它必须调用以下方法,该方法必须在UI线程上调用:

 var btDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress);

我知道你这样做的方法是将上面的内容封装在像ConnectToBluetoothDevice这样的异步方法中,然后像这样调用它:

dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ConnectToBTDevice(args));

到目前为止一切顺利。 我的问题是我无法获取对CoreDispatcher实例的引用,因此我可以进行上述调用。我尝试了很多方法:

  1. 反复呼叫:

    try
    {
      dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher;
    
    }
    catch (System.InvalidOperationException e)
    {
      Console.WriteLine("Cannot get dispatcher yet");
    }
    

    在启动应用程序很久之后,上面的内容总是落在catch块上。

  2. 注册Form.Shown回调的回调,然后尝试从当前的UI线程获取调度程序的实例,如下所示:

    var form = new Form1();
    form.Shown += FormShown;
    Application.Run(form);
    
    ...
    
    private static void FormShown(Object sender, EventArgs e)
    {
        var window = CoreWindow.GetForCurrentThread();
        if (window != null)
        {
            dispatcher = window.Dispatcher;
        }
    }
    

    在这种情况下,window总是为空,这让我感到惊讶,因为这个回调的重点在于它显示在窗体窗口之后。难道这个回调不应该在UI线程上,并返回它的CoreWindow吗?

  3. 我在这里缺少什么?如何从WinForms应用程序获取CoreDispatcher?

1 个答案:

答案 0 :(得分:2)

并非所有UWP API都可以从Classic Desktop应用程序访问。

您可以参考此MSDN link,其中说明可以从经典桌面应用调用仅具有 DualApiPartition属性的API。

查看CoreDispatcher的文档,您会发现不支持 DualApiPartition属性。

另外,经典桌面应用可以引用Dispatcher类,可以使用WindowsBase.dll命名空间通过System.Windows.Threading访问。