我有一个C#WinForms应用程序,可以在后台线程上扫描蓝牙设备。当需要连接到设备时,它必须调用以下方法,该方法必须在UI线程上调用:
var btDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress);
我知道你这样做的方法是将上面的内容封装在像ConnectToBluetoothDevice
这样的异步方法中,然后像这样调用它:
dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ConnectToBTDevice(args));
到目前为止一切顺利。 我的问题是我无法获取对CoreDispatcher实例的引用,因此我可以进行上述调用。我尝试了很多方法:
反复呼叫:
try
{
dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher;
}
catch (System.InvalidOperationException e)
{
Console.WriteLine("Cannot get dispatcher yet");
}
在启动应用程序很久之后,上面的内容总是落在catch块上。
注册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吗?
我在这里缺少什么?如何从WinForms应用程序获取CoreDispatcher?
答案 0 :(得分:2)
并非所有UWP API都可以从Classic Desktop应用程序访问。
您可以参考此MSDN link,其中说明可以从经典桌面应用调用仅具有 DualApiPartition
属性的API。
查看CoreDispatcher的文档,您会发现不支持 DualApiPartition
属性。
另外,经典桌面应用可以引用Dispatcher类,可以使用WindowsBase.dll
命名空间通过System.Windows.Threading
访问。