UWP迁移至.NET Framework4.8.1后Dispatcher构建失败的解决方案咨询
UWP转.NET Framework 4.8.1后Dispatcher兼容性问题
问题概述
原Visual Basic UWP项目(基于VS2022 17.6.3,使用Windows.UI.Core.CoreDispatcher处理跨线程UI更新)构建运行正常。转换为.NET Framework 4.8.1项目后,除Dispatcher相关代码外,其余部分映射正常,但因CoreDispatcher的引用版本冲突导致构建失败:
- UWP中CoreDispatcher来自
Windows.Foundation.UniversalApiContract, Version=14.0.0.0 - .NET Framework项目中自动引用的CoreDispatcher来自
Windows, Version=255.255.255.255,手动添加旧合约引用会引发大量额外错误。
UWP项目核心代码片段
MainPage类
Imports Windows.Devices.Enumeration Imports Windows.Devices.Bluetooth.GenericAttributeProfile Imports System.Text Imports Windows.Storage.Streams Imports System.Threading Public NotInheritable Class MainPage Dim BleDevices As New ObservableCollection(Of DeviceInformation)() Dim BleServices As New ObservableCollection(Of GattDeviceService)() Dim BleCharacteristic As New ObservableCollection(Of GattCharacteristic)() WithEvents GetBleDev As New GetBleDevice(Dispatcher) End Class
GetBleDevice类
Imports Windows.Devices.Bluetooth Imports Windows.Devices.Enumeration Imports Windows.UI.Core Public Class GetBleDevice Private ReadOnly KnownDevices As New ObservableCollection(Of DeviceInformation)() Private deviceWatcher As DeviceWatcher Public Event GetBleDevices(DevicesBle As ObservableCollection(Of DeviceInformation)) Private ReadOnly dispatcher As CoreDispatcher Public Sub New(iDispatcher As CoreDispatcher) dispatcher = iDispatcher End Sub End Class
.NET Framework 4.8.1项目问题代码片段
'Imports System.Collections.ObjectModel 'Imports Windows.Storage.Streams 'Imports System.Threading Imports Windows.Devices.Enumeration Imports Windows.Devices.Bluetooth.GenericAttributeProfile Imports System.ServiceModel Public Class Form1 Dim BleDevices As New ObservableCollection(Of DeviceInformation)() Dim BleServices As New ObservableCollection(Of GattDeviceService)() Dim BleCharacteristic As New ObservableCollection(Of GattCharacteristic)() WithEvents GetBleDev As New GetBleDevice(Dispatcher) End Class
解决办法
1. 替换Dispatcher实现(核心修复)
.NET Framework WinForms/WPF项目不兼容UWP的Windows.UI.Core.CoreDispatcher,需改用对应UI框架的线程同步机制:
- WinForms:使用
System.Windows.Forms.Control.Invoke/BeginInvoke,或SynchronizationContext.Current - WPF:使用
System.Windows.Threading.Dispatcher(控件自带的Dispatcher属性)
推荐使用SynchronizationContext实现跨框架兼容,修改步骤如下:
修改GetBleDevice类
Imports Windows.Devices.Bluetooth Imports Windows.Devices.Enumeration Imports System.Threading Public Class GetBleDevice Private ReadOnly KnownDevices As New ObservableCollection(Of DeviceInformation)() Private deviceWatcher As DeviceWatcher Public Event GetBleDevices(DevicesBle As ObservableCollection(Of DeviceInformation)) Private ReadOnly syncContext As SynchronizationContext ' 构造函数改为接收SynchronizationContext Public Sub New(context As SynchronizationContext) syncContext = context End Sub ' 示例:跨线程触发事件时使用syncContext切换到UI线程 Private Sub RaiseDeviceEvent() syncContext.Post(Sub() RaiseEvent GetBleDevices(KnownDevices) End Sub, Nothing) End Sub End Class
修改Form1初始化代码
Imports System.Collections.ObjectModel Imports Windows.Devices.Enumeration Imports Windows.Devices.Bluetooth.GenericAttributeProfile Imports System.Threading Public Class Form1 Dim BleDevices As New ObservableCollection(Of DeviceInformation)() Dim BleServices As New ObservableCollection(Of GattDeviceService)() Dim BleCharacteristic As New ObservableCollection(Of GattCharacteristic)() ' 传递当前UI线程的SynchronizationContext WithEvents GetBleDev As New GetBleDevice(SynchronizationContext.Current) End Class
2. 修复项目引用
- 安装NuGet包
Microsoft.Windows.SDK.Contracts:该包会自动引入正确版本的Windows Runtime合约,避免手动引用Windows.winmd或旧合约带来的冲突。 - 取消注释
Imports System.Collections.ObjectModel:ObservableCollection需要此命名空间。
3. 移除冗余引用
删除项目中不必要的引用(如Windows.winmd手动引用、冲突的WinRT合约引用),仅保留:
- WindowsBase.dll(WPF项目)
- System.Runtime.WindowsRuntime.dll
- 通过NuGet引入的
Microsoft.Windows.SDK.Contracts相关组件
内容的提问来源于stack exchange,提问作者HJA
相关产品推荐
相关产品推荐

