我可以使用CancellationToken取消StreamReader.ReadLineAsync吗? - c#

当我通过调用Cancel()CancellationTokenSource方法取消具有以下内容的异步方法时,它将最终停止。但是,由于Console.WriteLine(await reader.ReadLineAsync());行需要花很多时间才能完成,因此我也尝试将CancellationToken传递给ReadLineAsync()(期望它返回一个空字符串),以使该方法对我的Cancel()调用更具响应性。但是我无法将CancellationToken传递给ReadLineAsync()

我可以取消对Console.WriteLine()Streamreader.ReadLineAsync()的呼叫吗,如何取消?

为什么ReadLineAsync()不接受CancellationToken?我认为,为Async方法提供一个可选的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个字符(例如,将整个字符串转储到其中时),我仍然对如何取消此长时间运行的语句的任何建议或解决方法感兴趣,一份文件)。

参考方案

除非取消操作,否则您无法取消该操作。您可以使用WithCancellation扩展方法来使您的代码流表现得好像已被取消一样,但是基础仍将运行:

public static Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
{
    return task.IsCompleted // fast-path optimization
        ? task
        : task.ContinueWith(
            completedTask => completedTask.GetAwaiter().GetResult(),
            cancellationToken,
            TaskContinuationOptions.ExecuteSynchronously,
            TaskScheduler.Default);
}

用法:

await task.WithCancellation(cancellationToken);

您无法取消Console.WriteLine,也不需要取消。如果您有一个合理的string大小,这是瞬间的。

关于指南:如果您的实现实际上不支持取消,则您不应该接受令牌,因为它会发送混合消息。

如果确实有巨大的字符串要写入控制台,则不应使用Console.WriteLine。您可以一次在一个字符中写入字符串,并使该方法可取消:

public void DumpHugeString(string line, CancellationToken token)
{
    foreach (var character in line)
    {
        token.ThrowIfCancellationRequested();
        Console.Write(character);
    }

    Console.WriteLine();
}

更好的解决方案是分批写入而不是单个字符。这是使用MoreLinqBatch的实现:

public void DumpHugeString(string line, CancellationToken token)
{
    foreach (var characterBatch in line.Batch(100))
    {
        token.ThrowIfCancellationRequested();
        Console.Write(characterBatch.ToArray());
    }

    Console.WriteLine();
}

因此,结论是:

var reader = new StreamReader(dataStream);
while (!reader.EndOfStream)
{
    DumpHugeString(await reader.ReadLineAsync().WithCancellation(token), token);
}

使用Keycloak获取id_token - java

谁知道如何使用Keycloak获取id_token?我一直在Keycloak(Spring,JEE)和邮递员中使用Java。基础工作正常,但我需要id_token,因为有些说法称它们不在access_token中,但存在于id_token中。使用keycloak-core库,我可以获得Keycloak上下文,但是id_token属性始终为null。有想法吗 …

承载错误-invalid_token-找不到签名密钥 - c#

我有一个与.Net Core 2.2 API后端接口的Angular 7应用程序。这与Azure Active Directory连接。在Angular 7方面,它已通过AAD进行了正确的身份验证,并且我获得了有效的JWT,如在jwt.io上进行了验证。在.Net Core API方面,我创建了一个带有[Authorize]的简单测试API。当我从Angul…

LeetCode题解计算机为什么是基于二进制的?

可以是三进制么?二进制有什么好处?题解:为什么叫电子计算机?算盘应该没有二进制

LeetCode题解统计城市的所有灯泡

这个是我刚毕业的时候,一个真实的面试题,这是一个开放题。题目描述:想办法,将一个城市的所有灯泡数量统计出来。题解:费米估算法1、如果某个城市常驻人口有1000万2、假设每5人居住在一套房里,每套房有灯泡5只,那么住宅灯泡共有1000万只3、假设公众场所每10人共享一只灯泡,那么共有100万只4、主要的这两者相加就得出了1100万只当然实际上这是估算的,具体应…

LeetCode题解黑白圆盘

一个圆盘被涂上了黑白二色,两种颜色各占一个半圆。圆盘以一个未知的速度、按一个未知的方向旋转。你有一种特殊的相机可以让你即时观察到圆上的一个点的颜色。你需要多少个相机才能确定圆盘旋转的方向?题解:可以用一个相机即可