Skip to content

Commit 291a810

Browse files
authored
Make the cancelation can be executed before the task is done (#11225)
* Make the file large enough so that the cancelation can be executed before the task is done * Use StreamContent to indefinitely provide single char per couple dozens milliseconds * Use a fake stream that provides a single character A~Z per a couple of milliseconds without high memory cost instead * Correct the TimeSpan with Milliseconds * Change the implementation of Read() in the fake stream with simple logic and add a comment
1 parent a7bf111 commit 291a810

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

src/Tasks.UnitTests/DownloadFile_Tests.cs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void CanBeCanceled()
3737
DestinationFolder = new TaskItem(folder.Path),
3838
HttpMessageHandler = new MockHttpMessageHandler((message, token) => new HttpResponseMessage(HttpStatusCode.OK)
3939
{
40-
Content = new StringContent(new String('!', 10000000)),
40+
Content = new StreamContent(new FakeStream()),
4141
RequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://largedownload/foo.txt")
4242
}),
4343
SourceUrl = "http://largedownload/foo.txt"
@@ -47,7 +47,7 @@ public void CanBeCanceled()
4747

4848
downloadFile.Cancel();
4949

50-
task.Wait(TimeSpan.FromSeconds(1)).ShouldBeTrue();
50+
task.Wait(TimeSpan.FromMilliseconds(1500)).ShouldBeTrue();
5151

5252
task.Result.ShouldBeFalse();
5353
}
@@ -401,4 +401,40 @@ protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage reques
401401
}
402402
}
403403
}
404+
405+
// Fake stream that simulates providing a single character A~Z per a couple of milliseconds without high memory cost.
406+
public class FakeStream : Stream
407+
{
408+
private readonly int delayMilliseconds;
409+
410+
public FakeStream(int delayInMilliseconds = 20)
411+
{
412+
delayMilliseconds = delayInMilliseconds;
413+
Position = 0;
414+
}
415+
416+
public override bool CanRead => true;
417+
public override bool CanSeek => true;
418+
public override bool CanWrite => false;
419+
public override long Length => long.MaxValue;
420+
public override long Position { get; set; }
421+
422+
public override int Read(byte[] buffer, int offset, int count)
423+
{
424+
// Simulate infinite stream by keeping providing a single character to the beginning of the requested destination.
425+
// Writes next char A ~ Z in alphabet into the begining of requested destination. The count could be ignored.
426+
buffer[offset] = (byte)('A' + Position % 26);
427+
Position++;
428+
Task.Delay(delayMilliseconds).Wait();
429+
return 1;
430+
}
431+
432+
public override long Seek(long offset, SeekOrigin origin) => throw new NotImplementedException();
433+
434+
public override void SetLength(long value) => throw new NotImplementedException();
435+
436+
public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException();
437+
438+
public override void Flush() => throw new NotImplementedException();
439+
}
404440
}

0 commit comments

Comments
 (0)