WriteAsync 超时
WriteAsync with timeout
我尝试编写一个带有超时的简单异步写入代码,如下所示,并期望该函数在给定非常大的缓冲区和小的等待时间的情况下抛出 TaskCanceledException。但是,这不会发生。 WriteAsync 将阻塞数秒,直到写入完成。我错过了什么?
public async void 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 线程调用:
try
{
WriteWithTimeout(response.OutputStream, buf100M, w1ms);
}
catch(OperationCanceledException e)
{
ConsoleWriteLine("Failed with exception: {0}", e.Message);
}
您无法捕获异步无效。它必须 return 一个任务,你必须等待它。
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代码
try
{
await WriteWithTimeout(response.OutputStream, buf100M, w1ms);
}
catch(OperationCanceledException e)
{
ConsoleWriteLine("Failed with exception: {0}", e.Message);
}
取消仍然会发生,只是你没有注意到它们。
更新:
有可能 os.WriteAsync(
只是一个同步完成,只是由 Task.Run(
在幕后 1 支持。取消令牌不会取消已经 运行 Task.Run(
。在这种情况下,最好的方法是将取消包装在 Task.WhenAny(
中,并通过无限长的 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.例如,如果您不将 FileOptions.Asynchronous
传递给构造函数
,那么这是 FileStream
的默认行为
我尝试编写一个带有超时的简单异步写入代码,如下所示,并期望该函数在给定非常大的缓冲区和小的等待时间的情况下抛出 TaskCanceledException。但是,这不会发生。 WriteAsync 将阻塞数秒,直到写入完成。我错过了什么?
public async void 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 线程调用:
try
{
WriteWithTimeout(response.OutputStream, buf100M, w1ms);
}
catch(OperationCanceledException e)
{
ConsoleWriteLine("Failed with exception: {0}", e.Message);
}
您无法捕获异步无效。它必须 return 一个任务,你必须等待它。
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代码
try
{
await WriteWithTimeout(response.OutputStream, buf100M, w1ms);
}
catch(OperationCanceledException e)
{
ConsoleWriteLine("Failed with exception: {0}", e.Message);
}
取消仍然会发生,只是你没有注意到它们。
更新:
有可能 os.WriteAsync(
只是一个同步完成,只是由 Task.Run(
在幕后 1 支持。取消令牌不会取消已经 运行 Task.Run(
。在这种情况下,最好的方法是将取消包装在 Task.WhenAny(
中,并通过无限长的 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.例如,如果您不将 FileOptions.Asynchronous
传递给构造函数
FileStream
的默认行为