Skip to content

HidDevice.ReadAsync failed on .NET 6 #225

@cupsos

Description

@cupsos

Describe the issue

IOException occurred when HidDevice.ReadAsync on TFM .NET 6

Could be related with #224

Your Code

var hidFactory = new FilterDeviceDefinition(vendorId, productId).CreateWindowsHidDeviceFactory();
var device = await hidFactory.GetFirstDeviceAsync();
await device.InitializeAsync();
await device.WriteAsync(command);
var readResult = await device.ReadAsync(); // <-- exception here
System.IO.IOException : An error occurred while attempting to read from the device
---- System.IO.IOException : The parameter is incorrect.

  Stack Trace: 
HidDevice.ReadReportAsync(CancellationToken cancellationToken) line 139
HidDevice.ReadAsync(CancellationToken cancellationToken) line 121
OneTrayDispenserClient.RequestSensorStatusAsync() line 70
TaskExtensions.DumpAsync[T](Task`1 task) line 27
CommandTest.SensorStatus() line 26
--- End of stack trace from previous location ---
----- Inner Stack Trace -----
BufferedFileStreamStrategy.ReadFromNonSeekableAsync(Memory`1 destination, CancellationToken cancellationToken)
WindowsHidHandler.ReadReportAsync(CancellationToken cancellationToken) line 174
HidDevice.ReadReportAsync(CancellationToken cancellationToken) line 129

Info

  • Platform: Windows 11
  • Device Type: Hid
  • Version: 4.2.1 and develop branch 5524cda

Avoid this issue on .NET 6

Option 1: specify an AppContext switch or an environment variable

https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/filestream-position-updates-after-readasync-writeasync-completion#recommended-action

Follow this link for how to do. also i think this related with issue
But this could be effect to app performance..

Option 2: Use Read() than ReadAsync() in WindowsHidHandler.ReadReportAsync

public async Task<Report> ReadReportAsync(CancellationToken cancellationToken = default)
{
if (_readFileStream == null)
{
throw new NotInitializedException(Messages.ErrorMessageNotInitialized);
}
//Read the data
var bytes = new byte[ReadBufferSize.Value];
var bytesRead = (uint)await _readFileStream.ReadAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false);
var transferResult = new TransferResult(bytes, bytesRead);
//Log the data read
_logger.LogDataTransfer(new Trace(false, transferResult));
//Transform to a ReadReport
return _readTransferTransform(transferResult);
}

Option 3: FILE_FLAG_OVERLAPPED 0 in kernel32.CreateFile() on .NET 6

internal class ApiService : IApiService
{
#region Fields
#if NETFRAMEWORK
private const uint FILE_FLAG_OVERLAPPED = 0;
#else
private const uint FILE_FLAG_OVERLAPPED = 0x40000000;

Same approach as #223
but need to runtime check because preprocessor could not solve .net6(app) -> .netstandard2.0(user library) -> Hid.Net.
I will make PR soon by option 3

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions