Подтвердить что ты не робот

Использование ожидания внутри Interlocked.Exchange приводит к сбою компилятора С#

Игнорируйте на мгновение абсурдность await вызова Enumerable.Range. Это просто для того, чтобы вызвать крах-поведение. Это так же легко может быть методом, который выполняет некоторые сетевые операции ввода-вывода для создания коллекции объектов значений. (Действительно, именно там я увидел, что произошел сбой.)

Если я прокомментирую строку Interlocked.Exchange, компилятор не сработает.

public class Launcher
{
    private static IEnumerable<int> _foo;
    static void Main(string[] args)
    {
        DoWorkAsync().Wait();
    }

    private static async Task DoWorkAsync()
    {
        RefreshCache();
        foreach (var element in _foo)
        {
            Console.WriteLine(element);
        }

        Console.ReadLine();
    }

    private static async void RefreshCache()
    {
        Interlocked.Exchange(ref _foo, await Cache());
    }

    private static async Task<IEnumerable<int>> Cache()
    {
        return Enumerable.Range(0, 10);
    }
}

Изменение RefreshCache() на этом не позволяет компилятору сбой:

private static async void RefreshCache()
{
    var foo = await Cache();
    Interlocked.Exchange(ref _foo, foo);
}

Edit:

Еще более простое, самодостаточное воспроизведение, предоставляемое @Servy

public class Worker
{
    private static int foo;
    private static async void DoWork()
    {
        DoNothing(ref foo, await Task.FromResult(0));
    }

    private static void DoNothing(ref int item, int other)
    {
    }
}
4b9b3361