我使用kernel32.dll ReadFile读取已连接设备的HID输出。我想创建一个超时,因为此调用是一种阻塞方法,并且如果由于某种原因而挂起,则我的应用程序中的主循环也会挂起。
[DllImport("kernel32.dll", SetLastError = true)]
static internal extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);
public static HidLibrary.HidDeviceData.ReadStatus FastReadWithTimeout(this HidLibrary.HidDevice device, byte[] inputBuffer, int timeout)
{
return FastReadWithTimeoutWorker(device, inputBuffer, timeout).GetAwaiter().GetResult();
}
private static async Task<HidLibrary.HidDeviceData.ReadStatus> FastReadWithTimeoutWorker(HidLibrary.HidDevice device, byte[] inputBuffer, int timeout)
{
var task = Task.Run(async () => {
try
{
uint bytesRead;
if (NativeMethods.ReadFile(device.Handle, inputBuffer, (uint)inputBuffer.Length, out bytesRead, IntPtr.Zero))
{
return HidLibrary.HidDeviceData.ReadStatus.Success;
}
else
{
return HidLibrary.HidDeviceData.ReadStatus.NoDataRead;
}
}
catch (Exception)
{
return HidLibrary.HidDeviceData.ReadStatus.ReadError;
}
});
if (await Task.WhenAny(task, Task.Delay(timeout)) == task)
{
return task.Result;
}
else
{
device.CancelIO();
return HidLibrary.HidDeviceData.ReadStatus.WaitTimedOut;
}
}
问题是我当前执行此操作的方法导致了我无法允许的更多CPU开销。我执行此操作的方式有问题吗,还是有更好的方法在本机方法中实现超时?
我也刚刚发现了SetCommTimeouts(),但是在查找它的有效示例时遇到了麻烦,文档很杂乱。