2

我正在为 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 Store App 项目中调用时,此函数可以完美地连接到设备。但是,当从 Windows Store Apps 项目的单元测试库调用时,try 块中的语句会引发异常。

A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)

从我环顾四周的情况来看,当在没有 await 关键字的情况下调用 Async 函数时会发生这种情况。但我正在使用 await 关键字!

更多信息,我无法使用 NUnit 为商店应用程序编写单元测试,所以我使用 MSTest 框架。

[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 框架中的错误?

4

2 回答 2

2

我认为问题在于 await UsbDevice.FromIdAsync(deviceId); 必须在 UI 线程上调用,因为应用程序必须要求用户访问。

您必须使用 CoreDispatcher.RunAsync 以确保您在 UI 线程上或实际上在页面的代码中。

于 2014-06-11T17:34:09.860 回答
0

我在 VS 2017 中使用单元测试应用程序(通用 Windows)时遇到了同样的问题。我验证了我的前任 Greg Gorman 的答案(见下文)。我发现这是真的。如果您在方法体内使用此构造:

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();
  }
}
于 2017-09-02T06:51:12.970 回答