C# NetworkStream上的ReadAsync似乎正在使用我所有的CPU

C# NetworkStream上的ReadAsync似乎正在使用我所有的CPU,c#,asynchronous,profiling,networkstream,C#,Asynchronous,Profiling,Networkstream,我有下面的方法,它异步地从NetworkStream读取和反序列化数据包。一切都正常,但CPU评测显示,我等待异步读取的最后一行是我大部分CPU使用的来源 我是否实现得很糟糕/效率低下,或者NetworkStream的异步实现本身有什么问题 public async Task<Packet> ReadAsync(CancellationToken cancellationToken) { while (true) { // Read through t

我有下面的方法,它异步地从
NetworkStream
读取和反序列化数据包。一切都正常,但CPU评测显示,我等待异步读取的最后一行是我大部分CPU使用的来源

我是否实现得很糟糕/效率低下,或者
NetworkStream
的异步实现本身有什么问题

public async Task<Packet> ReadAsync(CancellationToken cancellationToken)
{
    while (true)
    {
        // Read through the available bytes until we find the start of a packet
        while (start < length && buffer[start] != Packet.STX)
            start++;

        // Align the packet (and all successive bytes) with the beginning of the buffer
        if (start > 0)
        {
            if (start < length)
                Array.Copy(buffer, start, buffer, 0, length - start);

            length -= start;
            start = 0;
        }

        // Read through the available bytes until we find the end of the packet
        while (end < length && buffer[end] != Packet.ETX)
            end++;

        // If we have a whole packet in the buffer, deserialize and return it
        if (end < length)
        {
            byte[] data = new byte[end + 1];
            Array.Copy(buffer, data, end + 1);
            byte[] decoded = null;
            Packet packet = null;

            try
            {
                decoded = Packet.Decode(data);
            }
            catch (Exception ex)
            {
                throw new IOException("Could not decode packet", ex);
            }

            if (decoded != null)
            {
                try
                {
                    packet = Packet.Deserialize(decoded);
                }
                catch (Exception ex)
                {
                    throw new IOException("Could not deserialize packet", ex);
                }
            }

            Array.Copy(buffer, end + 1, buffer, 0, length - (end + 1));
            length -= end + 1;
            end = 0;

            if (packet != null)
                return packet;
        }

        // If we read all available bytes while looking for the end of a packet
        if (end == length)
        {
            if (length == buffer.Length)
                throw new InsufficientMemoryException();

            length += await Stream.ReadAsync(buffer, length, buffer.Length - length, cancellationToken);
        }
    }
}
公共异步任务ReadAsync(CancellationToken CancellationToken) { while(true) { //读取可用字节,直到找到数据包的开头 while(start0) { 如果(开始<长度) 复制(buffer,start,buffer,0,length-start); 长度-=起点; 开始=0; } //通读可用字节,直到找到数据包的结尾 while(end

我已将代码更新为在每次调用
ReadAsync
之间休眠,大致相当于上次读取所用的时间:

var stopwatch = new Stopwatch();
var iteration = 0;

while (true)
{
    // ...
    var delay = stopwatch.Elapsed;
    stopwatch.Restart();

    if (iteration % 10 != 0)
        await Task.Delay(delay);

    length += await Stream.ReadAsync(buffer, length, buffer.Length - length, cancellationToken);
    stopwatch.Stop();
    iteration += 1;
}

这大大降低了CPU的使用率。这肯定是一个解决办法,因为它没有解决这个问题,但它是有效的。我很想听听其他人对这个问题的回答或意见。

我猜“这不是最终的假设”。ReadAsync必须进行系统调用才能将流读入缓冲区。代码的其余部分似乎没有做很多工作。评测是否认识到一个异步方法在几秒钟内没有返回,它本身没有使用该时间跨度?真正的问题是,在所有这些进行时,任务管理器之类的东西对CPU有何影响。我可以向您保证,
NetworkStream
的.NET实现没有问题。你的帖子中也没有任何东西支持“你所有的CPU”都被使用的说法。如果没有详细信息,如a和关于您正在使用的探查器以及(如果适用)您正在使用的探查模式(例如采样或检测),甚至不可能重现您的声明,更不用说解释了。对于您的声明,“NetworkStream的.NET实现
NetworkStream
”,那怎么办?我的问题和你描述的一样。除了睡觉或耽搁之外,我一直没能弄明白。我希望有一个更好的解决方案,但我想这将不得不做。为什么你有延迟去,因为阅读时间长?我想,一个简单的10毫秒就足够了。我们的客户往往每分钟左右发送一次请求,每个请求都包含在一个TCP数据包中。我想如果我有几千个连接调用任务,我仍然会看到高CPU使用率。我想每10毫秒延迟一次。一旦我对性能感到满意,我基本上就停止了实现,所以可能还有改进的空间,但我们还不需要它。