如何在 C# 中等待 kernel32 ReadFile() 或设置超时?

问题描述 投票:0回答:1

代码通常可以正常工作,但偶尔会出现无法捕获打印机响应的问题。因此,当尝试使用“writefile”方法向打印机发送附加字节时,它会收到先前的响应,并且新数据保留在打印机的队列中。我的想法是首先读取所有待处理的打印机响应,然后继续发送下一组字节,确保我收到预期的响应。当多个命令同时发送到打印机时,这一点尤其重要,并且我想确保收到我感兴趣的特定响应。

public Dictionary<string, string> ReadMany(List<string> settings)
{
    try
    {
        var Data = CreateReadManySettingXml(settings);

        // Check if the handle was successfully created
        if (Handle.IsInvalid)
        {
            throw new Exception("Failed to open handle to the device.");
        }

        // Write data to the device using the handle
        uint bytesWritten = 0;
        bool success = WriteFile(Handle, Data, (uint)Data.Length, out bytesWritten, IntPtr.Zero);

        // Check if the write was successful
        if (!success || bytesWritten != Data.Length)
        {
            throw new Exception("Failed to write to the device.");
        }

        // Read the response from the USB device
        byte[] readBuffer = new byte[10000];
        uint bytesRead = 0;

        success = ReadFile(Handle, readBuffer, 10000, out bytesRead, IntPtr.Zero);

        if (!success)
        {
            throw new Exception("Failed to read data from USB device.");
        }

        // Resize the buffer to the actual number of bytes read
        Array.Resize(ref readBuffer, (int)bytesRead);

        return ReadManyValues(Encoding.UTF8.GetString(readBuffer));

    }
    catch (Exception e)
    {
        throw new Exception(e.Message);
    }
}

我考虑使用“await”和“readfile”方法来处理这个问题,但这种方法似乎会导致代码卡在“readfile”方法上而无法进一步进行。

c# usb printers
1个回答
0
投票

您应该使用普通的

FileStream
来读取 USB,如确定哪个打印机名称对应于哪个设备 ID

中所述
// Write data to the device using the handle
uint bytesWritten = 0;
using var stream = new FileStream(Handle, FileAccess.ReadWrite, 0, true);
await stream.WriteAsync(Data, 0, Data.Length, CancellationToken.None);
// write will throw automatically

// Read the response from the USB device
byte[] readBuffer = new byte[10000];
uint bytesRead = 0;

var bytesRead = stream.ReadAsync(readBuffer, 0, 10000, CancellationToken.None);
// Do not resize buffer, just pass the correct offsets
var str = Encoding.UTF8.GetString(readBuffer, 0, bytesRead);
return ReadManyValues(str);
© www.soinside.com 2019 - 2024. All rights reserved.