You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带符号/无符号整数位移代码解析及Thread.Sleep异常原因咨询

代码逻辑解析与异常原因说明

一、代码逻辑拆解

先贴出修正了大小写问题的代码(原代码toArray()应为ToArray(),C#方法名遵循帕斯卡命名法):

using (MemoryStream mem = new MemoryStream(bytes.Skip(4).ToArray()))
{
    using (BinaryReader reader = new BinaryReader(mem))
    {
        UInt32 time1;
        UInt32 time2;
        Int64 time = 0;

        try
        {
            time1 = reader.ReadInt32();
            time2 = reader.ReadInt32();
            time = (((Int64)time2) << 32) | time1;

            return new DateTime(time);
        }
        catch
        {
        }
    }
}

这段代码的核心是从字节数组中解析时间戳并转换为DateTime对象,具体步骤如下:

  • 跳过无效前缀:通过bytes.Skip(4).ToArray()丢弃字节数组前4个字节,将剩余内容存入MemoryStream作为读取数据源。
  • 读取高低位整数:用BinaryReader读取两个32位整数,分别存入time1(低32位)和time2(高32位)。这里用ReadInt32()读带符号整数却赋值给无符号UInt32,本质是直接读取二进制位,不做符号转换。
  • 拼接64位时间值:把time2强制转为Int64后左移32位(腾出低32位空间),再和time1做按位或运算,将两个32位值拼接成完整的64位整数time。
  • 转换为DateTime:DateTime构造函数接受的Int64参数代表从0001年1月1日00:00:00起的100纳秒间隔数(Ticks),这段代码就是把拼接后的64位值当作Ticks生成时间对象。
  • 静默吞掉异常:空catch块会处理所有异常(比如字节数组剩余长度不足8字节、读取失败等),但这种写法会掩盖问题,不利于调试。

二、Thread.Sleep调用时的异常原因

Thread.Sleep的参数规则很明确:只能接受非负整数(0到Int32.MaxValue,即2147483647毫秒,约24.8天)或者-1(部分环境支持无限等待),超出范围就会抛出你看到的OutOfRange异常。

出现问题的核心是传给Thread.Sleep的参数不符合要求,常见场景有两种:

  1. 参数为负数:比如你用当前时间减去这段代码返回的DateTime得到TimeSpan,如果返回的时间比当前时间晚,TimeSpan.TotalMilliseconds会是负数,直接传给Thread.Sleep就会触发异常(仅-1是允许的负数)。
  2. 参数超出Int32最大值:如果直接把DateTime.Ticks转成毫秒传给Thread.Sleep,Ticks的值通常在10^17级别,远大于Int32.MaxValue;或者计算出的等待时间超过24.8天,也会触发异常。

补充:原代码用ReadInt32()给UInt32赋值存在风险,如果原始数据是无符号32位整数,应该用ReadUInt32()更准确,避免带符号转无符号时的意外值。

内容的提问来源于stack exchange,提问作者duk3th3c0d3r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:55:17