Проблема запуска нескольких задач, которая возвращает один и тот же результат - PullRequest
0 голосов
/ 09 ноября 2018

У меня есть код ниже (упрощен для чтения).Моя проблема в том, что задачи в списке полностью идентичны, если тип возвращаемого значения является типом значения (bool / int) и имеют одинаковое значение.Задачи больше не равны, если результатом является ссылочный тип (например, bool?) Или если, например, будет возвращаться другое значение типа int.

Я не понимаю, почему задачи равны, даже если они действительно работаютправильно (консоль записывает в журнал все 6 значений), может кто-нибудь объяснить или указать мне какую-нибудь документацию, которая могла бы объяснить это.

[TestMethod]
    public async Task RunMultipleTasks()
    {
        var list = new List<int> {0, 1, 2, 3, 4, 5};
        var tasks = list.Select(i => RunSimple(i)).ToList();
        var x = await Task.WhenAll(tasks);
        Assert.IsTrue(tasks[0]== tasks[1]);  
    }

    private async Task<bool> RunSimple(int i)
        {
            Console.WriteLine(i);
            return true;
        }

Также я заметил, что задача больше не идентична, если я добавляю задержку внутри метода RunSimpleили если я удалю асинхронный файл и верну Task.FromResult (true)

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Задачи кэшируются для общих случаев использования.


Конечный автомат, который генерирует компилятор при использовании ключевого слова async, использует структуру AsyncTaskMethodBuilder<TResult>. Для общего случая использования, такого как возвращение 0 для чисел или true или false для bools, для повышения производительности используется кэшированная задача. Код для этого можно найти в справочном источнике .


Это сообщение в блоге о ValueTasks описывает поведение более подробно.

0 голосов
/ 09 ноября 2018

Вы должны использовать:

await Task.Run(() => Console.WriteLine(i));

Вместо:

Console.WriteLine(i);

В методе RunSimple ().

0 голосов
/ 09 ноября 2018

Это потому, что RunSimple работает синхронно и возвращает постоянное значение. Я думаю, что компилятор заменяет его одной предварительно рассчитанной задачей. Постскриптум Task.FromResult (true) использует TaskCompletionSource для создания новой задачи каждый раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...