Почему значение AsyncLocal теряется между точками доходности IAsyncEnumerableC#

Место общения программистов C#
Ответить
Anonymous
 Почему значение AsyncLocal теряется между точками доходности IAsyncEnumerable

Сообщение Anonymous »

Рассмотрим следующий пример и, в частности, «функцию переноса»:

Код: Выделить всё

await foreach (var item in Wrap(Sequence()))
continue;

static IAsyncEnumerable Sequence()
{
return Core();

static async IAsyncEnumerable Core([EnumeratorCancellation] CancellationToken ct = default)
{
yield return 123;
await Task.Delay(TimeSpan.FromSeconds(5), ct);
yield return 456;
}
}

static IAsyncEnumerable Wrap(IAsyncEnumerable source)
{
return Core(source);

static async IAsyncEnumerable Core(IAsyncEnumerable source, [EnumeratorCancellation] CancellationToken ct = default)
{
Test.Context.Value = "Hello world";
await foreach (var value in source.WithCancellation(ct))
{
var before = Test.Context.Value; // Surely this should always be "Hello world", right?
yield return value;
var after = Test.Context.Value; // .. and surely this too?
Console.WriteLine($"Before={before}, after={after}");
}
}
}

static class Test
{
public static readonly AsyncLocal Context = new();
}
Я ожидал, что оба захваченных значения до и после будут содержать ранее установленный «Hello world».
Однако происходит следующее: для первой итерации before захватывает «Hello world», а after становится нулевым.
Для второй итерации этого цикла оба before< /code> и после имеют значение null.
  • Почему это так? Мне не совсем понятно, что и почему значение AsyncLocal очищается после этой первой точки текучести.
  • Как лучше всего переформулировать функцию Wrap, чтобы что значение AsyncLocal сохраняется для всего перечисления?


Подробнее здесь: https://stackoverflow.com/questions/793 ... eld-points
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»