具有超时的WriteAsync [英] WriteAsync with timeout

查看:122
本文介绍了具有超时的WriteAsync的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试编写一个具有超时的简单异步写入,如下所示,并且在缓冲区很大且等待时间很小的情况下,我希望该函数抛出TaskCanceledException。但是,这不会发生。 WriteAsync将阻塞许多秒钟,直到写入完成。我想念什么?

I try to code a simple async write with timeout as below and expect the function to throw a TaskCanceledException given a very large buffer and small waitTime. However, this does not happen. WriteAsync will block for many seconds until the write completes. What am I missing?

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


推荐答案

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

You can't catch a async void. It must return a task and you have to await it.

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

取消仍会发生,但您只是看不到它们。

The cancellations still happen but you just don't observe them.

更新:

os.WriteAsync(只是一个同步完成,由 Task.Run(在幕后 1 支持。取消令牌不会取消已经运行的 Task.Run(。在这种情况下,最好的方法是将取消内容包装在 Task.WhenAny(令牌也通过无限长的 Task.Delay(

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。例如,如果不将 FileOptions.Asynchronous 传递给构造函数,则这是 FileStream 的默认行为


1. For example that is the default behavior of a FileStream if you don't pass inFileOptions.Asynchronous to the constructor

这篇关于具有超时的WriteAsync的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆