当我调用我的CancellationTokenSource
的Cancel()
方法取消我的async方法时,它最终会停止,但是由于Console.WriteLine(await reader.ReadLineAsync());
行需要花费相当多的时间才能完成。我也尝试将我的CancellationToken
传递给ReadLineAsync()
(期望它返回一个空字符串),以便使方法更好地响应我的Cancel()
调用。然而,我无法将CancellationToken
传递给ReadLineAsync()
。
我可以取消对Console.WriteLine()
或Streamreader.ReadLineAsync()
的呼叫吗?如果可以,我该怎么做?
为什么ReadLineAsync()
不接受CancellationToken
?我认为给异步方法一个可选的CancellationToken
参数是一个很好的实践,即使该方法在被取消后仍然完成。
StreamReader reader = new StreamReader(dataStream);
while (!reader.EndOfStream)
{
if (ct.IsCancellationRequested){
ct.ThrowIfCancellationRequested();
break;
}
else
{
Console.WriteLine(await reader.ReadLineAsync());
}
}
- 更新**:正如下面的注解所述,由于每行40.000个字符的输入字符串格式很差,仅
Console.WriteLine()
调用就已经占用了几秒钟的时间。但我仍然对任何建议或工作区感兴趣,如果出于某种原因写入40,则如何取消这个长时间运行的语句。000个字符到一行中(例如,将整个字符串转储到文件中时)。
- 更新**:正如下面的注解所述,由于每行40.000个字符的输入字符串格式很差,仅
5条答案
按热度按时间7uzetpgm1#
.NET 6带来了Task.WaitAsync(CancellationToken)。因此,我们可以这样写:
在.NET 7(尚未发布)中,应该可以简单地编写:
基于https://github.com/dotnet/runtime/issues/20824和https://github.com/dotnet/runtime/pull/61898。
eulz3vhy2#
除非操作是可取消的,否则无法取消操作。可以使用
WithCancellation
扩展方法使代码流的行为如同操作被取消一样,但底层代码仍将运行:用法:
你不能取消
Console.WriteLine
,也不需要取消,如果你有一个合理大小的string
,它是即时的。关于指南:如果您的实现实际上不支持取消,则不应接受令牌,因为它会发送混合消息。
如果你有一个很大的字符串要写入控制台,你不应该使用
Console.WriteLine
,你可以一次写入一个字符,并且让那个方法是可取消的:一个更好的解决方案是批量写入而不是单个字符。下面是一个使用
MoreLinq
的Batch
的实现:所以,总结一下:
pxy2qtax3#
我将answer推广为:
现在您可以在任何可取消的异步方法上使用取消令牌。例如WebRequest.GetResponseAsync:
将变为:
参见示例http://pastebin.com/KauKE0rW
lymnna714#
我喜欢使用无限延迟,代码很干净。如果
waiting
完成,WhenAny
返回,cancellationToken
抛出。否则,task
的结果将返回。gzjq41n45#
你不能取消
Streamreader.ReadLineAsync()
。恕我直言,这是因为阅读一行应该很快。但是你可以通过使用一个单独的任务变量来很容易地阻止Console.WriteLine()
的发生。对
ct.IsCancellationRequested
的检查也是多余的,因为ct.ThrowIfCancellationRequested()
仅在请求取消时才会抛出。