Реализация ReadFile с тайм-аутом, вызывающим слишком большую загрузку ЦП - PullRequest
0 голосов
/ 18 ноября 2018

Я использую ReadFile kernel32.dll для чтения 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;
        }
    }

Проблема заключается в моем текущем методе выполнения этого, вызывающем больше ЦПнакладные расходы, чем я могу позволить.Есть ли что-то не так с тем, как я это делаю, или есть лучший способ реализовать тайм-аут в нативном методе?

Я также только что обнаружил SetCommTimeouts (), но у меня возникают проблемы с поиском рабочего примера, документация пятнистая.

...