예제 #1
0
        static async Task <byte[]> readExactAsync
            (int count, Func <byte[], int, int, object> readFunc, ReadExactInfo info)
        {
            var timeouter = new Timeouter(info.MethodTimeout);

            var buffer         = new byte[count];
            var offset         = 0;
            var totalBytesRead = 0;
            var remain         = count;

            while (totalBytesRead != count)
            {
                var bytesRead = 0;
                var readInfo  = readFunc(buffer, offset, remain);
                if (readInfo is Task <int> task)
                {
                    bytesRead = await task;
                }
                else if (readInfo is int read)
                {
                    bytesRead = read;
                }
                else
                {
                    throw new NotSupportedException();
                }
                totalBytesRead += bytesRead;
                offset          = totalBytesRead;
                remain          = count - totalBytesRead;

                if (bytesRead == 0 && info.ThrowIfZeroReceived)
                {
                    throw new ReadExactZeroReceivedException();
                }
                if (info.RetryDelay != 0)
                {
                    await Task.Delay(info.RetryDelay).ConfigureAwait(false);
                }
                if ((info.TimeoutOnlyIfNothingWasRead && totalBytesRead == 0) ||
                    (!info.TimeoutOnlyIfNothingWasRead))
                {
                    timeouter.ThrowIfTimeout(() => new ReadExactTimeoutException(buffer.Take(totalBytesRead), count));
                }
            }

            return(buffer);
        }
예제 #2
0
 public static async Task <byte[]> ReadExactAsync(this Stream stream, int count, ReadExactInfo info,
                                                  CancellationToken cancellation)
 {
     return(await readExactAsync(count, (a, b, c) => stream.ReadAsync(a, b, c, cancellation), info));
 }