gpt4 book ai didi

c# - 使用 EnumeratorCancellation 返回 AsyncEnumerable 或循环 WithCancellation 有什么区别

转载 作者:行者123 更新时间:2023-12-01 13:12:02 25 4
gpt4 key购买 nike

我有以下方法可以从 http 流中读取 csv 文档

public async IAsyncEnumerable<Line> GetLines([EnumeratorCancellation] CancellationToken cancellationToken)
{
HttpResponseMessage response = GetResponse();

using var responseStream = await response.Content.ReadAsStreamAsync();
using var streamReader = new StreamReader(responseStream);
using var csvReader = new CsvReader(streamReader);

while (!cancellationToken.IsCancellationRequested && await csvReader.ReadAsync())
{
yield return csvReader.GetRecord<Line>();
}
}

以及其他地方使用结果的方法
var documentAsyncEnumerable = graphClient.GetLines(cancellationToken);
await foreach (var document in documentAsyncEnumerable.WithCancellation(cancellationToken))
{
// Do something with document
}

我的问题是我应该在一个地方使用取消 token 吗?应该在产生记录之前对取消 token 采取行动还是 IAsyncEnumerable.WithCancellation() 基本上做同样的事情?如果有的话有什么区别?

最佳答案

在幕后,取消 token 被传递给 GetAsyncEnumerator方法无论如何,根据sources

namespace System.Collections.Generic
{
public interface IAsyncEnumerable<out T>
{
IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default);
}

public interface IAsyncEnumerator<out T> : IAsyncDisposable
{
ValueTask<bool> MoveNextAsync();
T Current { get; }
}
}

您应该使用 cancellationToken仅一次,直接通过或使用 WithCancellation ,这些方法都是一样的。 WithCancellationIAsyncEnumerable<T> 的扩展方法,接受 CancellationToken作为参数(它使用与 ConfigureAwait 相同的模式)。如果是 [EnumeratorCancellation]编译器生成将 token 传递给 GetAsyncEnumerator 的代码方法

MSDN magazine中描述了两种不同方式的原因。

Why two different ways to do it? Passing the token directly to the method is easier, but it doesn’t work when you’re handed an arbitrary IAsyncEnumerable from some other source but still want to be able to request cancellation of everything that composes it. In corner-cases, it can also be advantageous to pass the token to GetAsyncEnumerator, as doing so avoids “burning in” the token in the case where the single enumerable will be enumerated multiple times: By passing it to GetAsyncEnumerator, a different token can be passed each time.

关于c# - 使用 EnumeratorCancellation 返回 AsyncEnumerable 或循环 WithCancellation 有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59300561/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com