visa
This commit is contained in:
@@ -195,13 +195,21 @@ namespace DeviceCommand.Base
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取定长原始二进制字节(用于 IT6720 等自定义二进制帧协议)。
|
||||
/// <para>VISA 会话在 <see cref="ResetConnection"/> 中默认启用了以 <c>\n</c>(0x0A) 为终止符的文本读取;
|
||||
/// 而二进制帧的数据区可能恰好包含 0x0A 字节,若不禁用终止符,<c>RawIO.Read</c> 会在该字节处提前结束,
|
||||
/// 导致返回长度不足、帧校验失败。故本方法读取期间临时关闭终止符,读完再由 finally 恢复。</para>
|
||||
/// <para>单次 <c>RawIO.Read(count)</c> 只保证返回「至多 count」字节,可能因分包而少于请求长度;
|
||||
/// 这里参照 <see cref="ReadRawUntilEnd"/> 的做法循环补足,直到读满 length 或发生超时/END/流终止。</para>
|
||||
/// </summary>
|
||||
public async Task<byte[]> ReadAsync(int length, CancellationToken ct = default)
|
||||
{
|
||||
await _commLock.WaitAsync(ct);
|
||||
try
|
||||
{
|
||||
EnsureConnected();
|
||||
return await Task.Run(() => _session!.RawIO.Read(length), ct);
|
||||
return await Task.Run(() => ReadExactBytes(length), ct);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -209,6 +217,50 @@ namespace DeviceCommand.Base
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步读取定长二进制字节:关闭终止符后循环补足,直到读满 <paramref name="length"/> 字节;
|
||||
/// 超时/END/流终止导致读不满时按实到长度截断返回(由上层按帧长校验判定成功与否)。
|
||||
/// </summary>
|
||||
private byte[] ReadExactBytes(int length)
|
||||
{
|
||||
if (length <= 0) return Array.Empty<byte>();
|
||||
|
||||
bool prevTermEnabled = _session!.TerminationCharacterEnabled;
|
||||
// 二进制帧数据可能含 0x0A,读取全程禁用终止符,避免被误判为帧结束而截断
|
||||
_session!.TerminationCharacterEnabled = false;
|
||||
try
|
||||
{
|
||||
var buffer = new byte[length];
|
||||
int offset = 0;
|
||||
while (offset < length)
|
||||
{
|
||||
byte[] chunk;
|
||||
try
|
||||
{
|
||||
chunk = _session!.RawIO.Read(length - offset);
|
||||
}
|
||||
catch (Exception) when (offset > 0)
|
||||
{
|
||||
// 已收到部分数据后再超时/异常:返回已收字节,交由上层按帧长校验处理
|
||||
break;
|
||||
}
|
||||
if (chunk == null || chunk.Length == 0) break;
|
||||
Buffer.BlockCopy(chunk, 0, buffer, offset, chunk.Length);
|
||||
offset += chunk.Length;
|
||||
}
|
||||
|
||||
if (offset == length) return buffer;
|
||||
// 实际读到的字节少于请求长度:按实到长度截断返回,避免尾部填充 0
|
||||
var trimmed = new byte[offset];
|
||||
Buffer.BlockCopy(buffer, 0, trimmed, 0, offset);
|
||||
return trimmed;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_session!.TerminationCharacterEnabled = prevTermEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> ReadAsync(string delimiter = "\n", CancellationToken ct = default)
|
||||
{
|
||||
await _commLock.WaitAsync(ct);
|
||||
|
||||
Reference in New Issue
Block a user