|
7 | 7 |
|
8 | 8 | namespace MySql.Data.Protocol.Serialization |
9 | 9 | { |
10 | | - internal static class ProtocolUtility |
11 | | - { |
| 10 | + internal static class ProtocolUtility |
| 11 | + { |
12 | 12 | public static ValueTask<Packet> ReadPacketAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func<int> getNextSequenceNumber, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior) |
13 | 13 | { |
14 | 14 | var headerBytesTask = bufferedByteReader.ReadBytesAsync(byteHandler, 4, ioBehavior); |
@@ -135,14 +135,25 @@ public static ValueTask<int> WritePacketAsync(IByteHandler byteHandler, int sequ |
135 | 135 | SerializationUtility.WriteUInt32((uint) contents.Count, buffer, 0, 3); |
136 | 136 | buffer[3] = (byte) sequenceNumber; |
137 | 137 | Buffer.BlockCopy(contents.Array, contents.Offset, buffer, 4, contents.Count); |
138 | | - return byteHandler.WriteBytesAsync(new ArraySegment<byte>(buffer, 0, bufferLength), ioBehavior) |
139 | | - .ContinueWith(x => |
| 138 | + var task = byteHandler.WriteBytesAsync(new ArraySegment<byte>(buffer, 0, bufferLength), ioBehavior); |
| 139 | + if (task.IsCompletedSuccessfully) |
| 140 | + { |
| 141 | + ArrayPool<byte>.Shared.Return(buffer); |
| 142 | + return default(ValueTask<int>); |
| 143 | + } |
| 144 | + return AddContinuation(task, buffer); |
| 145 | + |
| 146 | + // NOTE: use a local function (with no captures) to defer creation of lambda objects |
| 147 | + ValueTask<int> AddContinuation(ValueTask<int> task_, byte[] buffer_) |
| 148 | + { |
| 149 | + return task_.ContinueWith(x => |
140 | 150 | { |
141 | | - ArrayPool<byte>.Shared.Return(buffer); |
| 151 | + ArrayPool<byte>.Shared.Return(buffer_); |
142 | 152 | return default(ValueTask<int>); |
143 | 153 | }); |
| 154 | + } |
144 | 155 | } |
145 | 156 |
|
146 | | - public const int MaxPacketSize = 16777215; |
147 | | - } |
| 157 | + public const int MaxPacketSize = 16777215; |
| 158 | + } |
148 | 159 | } |
0 commit comments