I am writing a Stream class and am blocked in the ReadAsync method. Please take a look at the code, I think it can explain the situation better that I can do it with my English.
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken)
{
if (!cancellationToken.IsCancellationRequested)
{
return _connection.ReceiveAsync(new ArraySegment<byte>(buffer, offset, count));
}
return // <--------------- what here?
}
Using ILSpy I can see that other Stream classes return a cancelled task as follow:
return new Task<TResult>(true, default(TResult), TaskCreationOptions.None, cancellationToken);
However that Task's constructor is internal and I cannot invoke it.
Google didn't help me at all.
The most direct way I know to create a canceled task is to use a TaskCompletionSource
:
var tcs = new TaskCompletionSource<int>();
tcs.TrySetCanceled();
return tcs.Task;
If you haven't used it before, TaskCompletionSource
provides a "promise-style" task, which basically allows you to say, "Here, take this Task
now, and I'll provide the result (or report an error/cancellation) whenever I'm ready." It's useful when you want to schedule/coordinate work yourself, as opposed to simply relying on a TaskScheduler
.
Alternatively, if you rewrite your method using async/await
, you can force the cancellation exception to automatically propagate to the result Task
:
public async override Task<int> ReadAsync(
byte[] buffer,
int offset,
int count,
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
return await _connection.ReceiveAsync(
new ArraySegment<byte>(
buffer,
offset,
count));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With