你无法捕获 async void。它必须返回一个任务,而你必须等待它。
public async Task WriteWithTimeout(Stream os, byte[] buf, int waitMs)
{
CancellationTokenSource tokenSource = new CancellationTokenSource(waitMs); // cancel after waitMs milliseconds.
await os.WriteAsync(buf, 0, buf.Length, tokenSource.Token);
return;
}
gui code
try
{
await WriteWithTimeout(response.OutputStream, buf100M, w1ms);
}
catch(OperationCanceledException e)
{
ConsoleWriteLine("Failed with exception: {0}", e.Message);
}
取消仍然会发生,但你只是没有观察到它们。
Update:
It is possible that os.WriteAsync(
is just a synchronous completion just backed by a Task.Run(
behind the scenes1. The cancellation token won't cancel a already running Task.Run(
. In that case the best way is to wrap the cancellation up in a Task.WhenAny(
and pass in the token to there too via a infinitely long Task.Delay(
.
public async Task WriteWithTimeout(Stream os, byte[] buf, int waitMs)
{
CancellationTokenSource tokenSource = new CancellationTokenSource(waitMs); // cancel after waitMs milliseconds.
var task = os.WriteAsync(buf, 0, buf.Length, tokenSource.Token);
var waitedTask = await Task.WhenAny(task, Task.Delay(-1, token));
await waitedTask; //Wait on the returned task to observe any exceptions.
}
1. For example that is the default behavior of a FileStream
if you don't pass inFileOptions.Asynchronous
to the constructor