FtpServer icon indicating copy to clipboard operation
FtpServer copied to clipboard

Cancellation of FtpConnection.ReadFromStreamAsync causes UnobservedTaskException

Open cjzzz opened this issue 3 years ago • 1 comments

In FtpConnection.ReadFromStreamAsync, readTask is started using the cancellation token passed into the method, but tcs is also created which has its result set when the cancellation token is cancelled:

protected override async Task<int> ReadFromStreamAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
{
	var readTask = Stream
	   .ReadAsync(buffer, offset, length, cancellationToken);

	var tcs = new TaskCompletionSource<object?>();
	using var registration = cancellationToken.Register(() => tcs.TrySetResult(null));
	var resultTask = await Task.WhenAny(readTask, tcs.Task)
	   .ConfigureAwait(false);

	if (cancellationToken.IsCancellationRequested)
	{
		Logger?.LogTrace("Cancelled through CancellationToken");
		return 0;
	}
...

This can cause resultTask to complete when tcs.Task is complete, and the exception from the cancellation of readTask is never observed. causing an UnobservedTaskException.

cjzzz avatar Jun 08 '22 22:06 cjzzz

Nice catch!

fubar-coder avatar Jun 09 '22 17:06 fubar-coder