public async Task CancelPendingFlushLostOfCancellationsNoDataLost() { var writeSize = 16; var singleWriteStream = new SingleWriteStream(); MemoryStream = singleWriteStream; Writer = new StreamPipeWriter(MemoryStream, minimumSegmentSize: writeSize); for (var i = 0; i < 10; i++) { FlushResult flushResult = new FlushResult(); var expectedData = Encoding.ASCII.GetBytes(new string('a', writeSize)); var tcs = new TaskCompletionSource <int>(TaskCreationOptions.RunContinuationsAsynchronously); var task = Task.Run(async() => { try { // Create two Segments // First one will succeed to write, other one will hang. for (var j = 0; j < 2; j++) { Writer.Write(expectedData); } var flushTask = Writer.FlushAsync(); tcs.SetResult(0); flushResult = await flushTask; } catch (Exception ex) { Console.WriteLine(ex.Message); throw ex; } }); await tcs.Task; Writer.CancelPendingFlush(); await task; Assert.True(flushResult.IsCanceled); } // Only half of the data was written because every other flush failed. Assert.Equal(16 * 10, ReadWithoutFlush().Length); // Start allowing all writes to make read succeed. singleWriteStream.AllowAllWrites = true; Assert.Equal(16 * 10 * 2, Read().Length); }
public async Task CancelPendingFlushBetweenWritesAllDataIsPreserved() { MemoryStream = new SingleWriteStream(); Writer = new StreamPipeWriter(MemoryStream); FlushResult flushResult = new FlushResult(); var tcs = new TaskCompletionSource <int>(TaskCreationOptions.RunContinuationsAsynchronously); var task = Task.Run(async() => { try { await Writer.WriteAsync(Encoding.ASCII.GetBytes("data")); var writingTask = Writer.WriteAsync(Encoding.ASCII.GetBytes(" data")); tcs.SetResult(0); flushResult = await writingTask; } catch (Exception ex) { Console.WriteLine(ex.Message); throw ex; } }); await tcs.Task; Writer.CancelPendingFlush(); await task; Assert.True(flushResult.IsCanceled); await Writer.WriteAsync(Encoding.ASCII.GetBytes(" more data")); Assert.Equal(Encoding.ASCII.GetBytes("data data more data"), Read()); }