问题
I use kernel32.dll ReadFile to read the HID output of a connected device. I wanted to create a timeout because this call is a blocking method and if it hangs for any reason the main loop in my application also hangs.
[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;
}
}
The issue is my current method of doing this causing more CPU overhead than I can allow. Is there something wrong with the way I am doing this or is there a better way to implement a timeout in a native method?
I also just discovered SetCommTimeouts(), but am having trouble finding a working example of it, documentation is spotty.
来源:https://stackoverflow.com/questions/53362883/implementing-a-readfile-with-a-timeout-inducing-too-much-cpu-ussage