public static async Task <Frame> ReadAsync(Stream stream, CancellationToken ct) { try { var frameletCount = await ReadUInt16Async(stream, ct); if (frameletCount == 0) { throw new EpoxyProtocolErrorException("Zero framelets"); } var frame = new Frame(frameletCount); while (frameletCount > 0) { if (ct.IsCancellationRequested) { return(null); } var frameletType = await ReadUInt16Async(stream, ct); if (!Framelet.IsKnownType(frameletType)) { throw new EpoxyProtocolErrorException("Unknown framelet type: " + frameletType); } var frameletLength = await ReadUInt32Async(stream, ct); if (frameletLength > int.MaxValue) { throw new EpoxyProtocolErrorException("Framelet too big: " + frameletLength); } byte[] frameletContents = await ReadBufferAsync(stream, unchecked ((int)frameletLength), ct); frame.Add(new Framelet((FrameletType)frameletType, new ArraySegment <byte>(frameletContents))); --frameletCount; } return(frame); } catch (Exception ex) when(ex is OperationCanceledException || ex is EndOfStreamException || ex is ObjectDisposedException) { return(null); } }