我正在为Windows应用商店应用编写USB设备API,它使用Windows 8.1中的Windows.Devices.USB API连接自定义USB设备并与之通信。我正在使用Visual Studio 2013开发预览IDE。 库中的以下功能用于连接USB设备。 (为简洁起见,简化)
public static async Task<string> ConnectUSB()
{
string deviceId = string.Empty;
string result = UsbDevice.GetDeviceSelector(new Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"));
var myDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(result, null);
if (myDevices.Count > 0)
{
deviceId = myDevices[0].Id;
}
UsbDevice usbDevice = null;
try
{
usbDevice = await UsbDevice.FromIdAsync(deviceId);
}
catch (Exception)
{
throw;
}
if (usbDevice != null)
return "Connected";
return string.Empty;
}
从Windows应用商店应用项目调用时,此功能可以完美连接到设备。但是,从Windows Store Apps项目的单元测试库调用时,try块中的语句会引发异常。
A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)
从我看过来看,当没有await关键字调用Async函数时会发生这种情况。但我正在使用await关键字好吧!
更多信息,我无法使用NUnit为Store Apps编写单元测试,因此使用的是MSTest Framework。
[TestClass]
public class UnitTest1
{
[TestMethod]
public async Task TestMethod1()
{
await ConnectToUSB.ConnectUSB();
}
}
此外,我在App Store项目的清单文件中也包含了以下功能标签,没有这些标签,Store Apps就无法连接到设备。
<m2:DeviceCapability Name="usb">
<m2:Device Id="vidpid:ZZZZ XXXX">
<m2:Function Type="name:vendorSpecific" />
</m2:Device>
</m2:DeviceCapability>
我是否缺少某些东西,或者这是MSTest框架中的错误?
答案 0 :(得分:2)
我认为问题在于此 等待UsbDevice.FromIdAsync(deviceId); 必须在UI线程上调用,因为应用程序必须要求用户访问。
您必须使用CoreDispatcher.RunAsync以确保您处于UI线程或实际位于页面后面的代码中。
答案 1 :(得分:0)
我在VS 2017中遇到了与单元测试应用程序(通用Windows)相同的问题。 我验证了我的前任格雷格戈尔曼的答案(见下文)。我发现这是真的。 如果您使用内部方法体,则构造:
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
async () =>
{
...
UsbDevice usbDevice = await UsbDevice.FromIdAsync(deviceId);
...
}).AsTask().Wait();
FromIDAsync将按预期工作。
对于您的示例,将测试方法更改为:
[TestClass]
public class UnitTest1
{
[TestMethod]
public async Task TestMethod1()
{
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
async () =>
{
await ConnectToUSB.ConnectUSB();
}).AsTask().Wait();
}
}