c# - WriteAsync 超时

标签 c# async-await outputstream cancellationtokensource

我尝试编写一个带有超时的简单异步写入代码,如下所示,并期望该函数在给定非常大的缓冲区和小等待时间的情况下抛出 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);
}        

最佳答案

您无法捕获异步无效。它必须返回一个任务,您必须等待它。

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;
}

界面代码

try
{
    await WriteWithTimeout(response.OutputStream, buf100M, w1ms);
}
catch(OperationCanceledException e)
{
    ConsoleWriteLine("Failed with exception: {0}", e.Message);
}

取消仍然会发生,只是您没有观察到它们。

更新:

有可能 os.WriteAsync( 只是由 Task.Run( 在幕后支持的同步完成1。取消 token 不会取消已经运行的 Task.Run(。在这种情况下,最好的方法是将取消包装在 Task.WhenAny( 中并传入 token 也通过无限长的 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 的默认行为

关于c# - WriteAsync 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47784152/

相关文章:

c# - 如何使用 Infragistics XamDataGrid 将所选项目绑定(bind)到模型?

javascript - 如何在 Node.js 中使用 async/await 编写依赖项

一旦内容可用,Java 就会从 Stream 中读取

java - 如何强制java OutputStreamWriter实际写入单个字节?

c# - C#中的一种调用方式

c# - .NET 4.5 中的代码契约 + 异步 : "The method or operation is not implemented"

c# - 如何使用 C# 编写自动化系统测试?

c# - 无法将 'DataTable' 隐式转换为 'Task<DataTable>'

reactjs - axios嵌套请求函数返回

java - 保存到Java中的目标文件: getParentFile()