我可以用CancellationToken取消StreamReader.ReadLineAsync吗?当我通过调用CancellationTokenSource的Cancel()方法取消()具有以下内容的异步方法时,它终于停止了。但由于Console.WriteLine(awaitreader.ReadLineAsync());线Console.WriteLine(awaitreader.ReadLineAsync());需要很多时间才能完成,我正在尝试将我的CancellationToken传递给ReadLineAsync()(期望它返回一个空字符串)以使该方法对我的Cancel()调用更敏感。但我无法将CancellationToken传递给ReadLineAsync()。我可以取消对Console.WriteLine()或Streamreader.ReadLineAsync()的调用吗?如果可以,我该怎么做?为什么ReadLineAsync()不接受CancellationToken?我认为给Async方法一个可选的CancellationToken参数是一个很好的做法,即使该方法在被取消后仍然完成。StreamReaderreader=newStreamReader(dataStream);while(!reader.EndOfStream){if(ct.IsCancellationRequested){ct.ThrowIfCancellationRequested();休息;}else{Console.WriteLine(awaitreader.ReadLineAsync());}}更新正如下面评论中提到的,由于每行40.000个字符的格式错误的输入字符串,Console.WriteLine()调用已经花费了几秒钟。打破这个解决了我的响应时间问题,但我仍然对如何取消这个长时间运行的语句的任何建议或解决方法感兴趣,如果出于某种原因你打算在一行中写40.000个字符(例如将整个字符串转储到一个文件)。您无法取消操作,除非它可以被取消。您可以使用WithCancellation扩展方法使代码流表现得就像被取消一样,但底层仍将运行:?任务:task.ContinueWith(completedTask=>completedTask.GetAwaiter().GetResult(),cancellationToken,TaskContinuationOptions.ExecuteSynchronously,TaskScheduler.Default);用法:等待task.WithCancellation(cancellationToken);您不能取消Console.WriteLine也不需要。如果你有一个合理大小的字符串,它是即时的。关于准则:如果您的实现实际上不支持取消,则您不应接受令牌,因为它会发送混合消息。如果要写入控制台的字符串很大,则不应使用Console.WriteLine。一次可以把字符串写成字符,方法可以取消:publicvoidDumpHugeString(stringline,CancellationTokentoken){控制台。写入(字符);}控制台.WriteLine();更好的解决方案是分批写入而不是单个字符。这是使用MoreLinqBatch:publicvoidDumpHugeString(stringline,CancellationTokentoken){foreach(varcharacterBatchinline.Batch(100)){token.ThrowIfCancellationRequested();Console.Write(characterBatch.ToArray());}控制台.WriteLine();}所以,最后:varreader=newStreamReader(dataStream);while(!reader.EndOfStream){DumpHugeString(awaitreader.ReadLineAsync().WithCancellation(token),token);}我将这个回答概括为:}catch(Exceptionex){if(cancellationToken.IsCancellationRequested){//异常将作为Exception.InnerException可用thrownewOperationCanceledException(ex.Message,ex,cancellationToken);}//没有请求取消,重新抛出原来的Exceptionthrow;}}}您现在可以在任何可取消的异步方法上使用取消令牌,例如WebRequest.GetResponseAsync:varrequest=(HttpWebRequest)WebRequest.Create(url);使用(varresponse=awaitrequest.GetResponseAsync()){...}会变成:varrequest=(HttpWebRequest)WebRequest.Create(url);使用(WebResponseresponse=awaitrequest.GetResponseAsync().WithCancellation(CancellationToken.None,request.Abort,true)){。..另请参阅示例http://pastebin.com/KauKE0rW您无法取消Streamreader.ReadLineAsync()。恕我直言,这是因为阅读一行应该非常快。但是您可以使用单独的任务变量轻松防止Console.WriteLine()发生。ct.IsCancellationRequested的检查也是多余的,因为ct.ThrowIfCancellationRequested()只会在请求取消时抛出。StreamReaderreader=newStreamReader(dataStream);while(!reader.EndOfStream){ct.ThrowIfCancellationRequested();字符串行=等待reader.ReadLineAsync());ct.ThrowIfCancellationRequested();控制台.WriteLine(线);我喜欢无限延迟,代码很干净。如果等待完成WhenAny返回并且WhenAny将抛出。否则,将返回任务的结果。以上是C#学习教程:CanIcancelStreamReader.ReadLineAsyncwithCancellationToken?如果分享的内容对你有用,需要进一步了解C#学习教程,希望你多多关注——.CreateLinkedTokenSource(cancellationToken)){varwaiting=Task.Delay(-1,delayCTS.Token);vardoing=任务;等待Task.WhenAny(等待,做);delayCTS.Cancel();cancellationToken.ThrowIfCancellationRequested();}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
