Задачи выполняются последовательно по какой-то причине

Случай 1: у меня есть консольное тестовое приложение и библиотеки. Тестовое приложение вызывает асинхронные методы для классов в тех библиотеках, которые предназначены для параллельной работы. Пример кода

        for (int i = 0; i < 100; i++)
        {
            var myTask = RetrieveRecordSet<TestClass3>();
        }

Это работает, как и ожидалось, в консольном приложении, то есть все 100 задач ставятся в очередь одновременно, а задачи выполняются параллельно в фоновом режиме, что подтверждается их выходными данными консоли.

Случай 2: тот же код, только в приложении WPF вместо консольного приложения. Теперь по какой-то причине задачи выполняются последовательно.

Случай 3: я также попробовал следующую модификацию приложения WPF безрезультатно:

        for (int i = 0; i < 100; i++)
        {
            var myTask = Task.Factory.StartNew(() => RetrieveRecordSet<TestClass3>());
        }

Случай 4: Затем я попробовал следующее, но он блокирует пользовательский интерфейс и все еще последовательный

        Parallel.For(0, 100, a => RetrieveRecordSet<TestClass3>());

Есть ли способ получить такое же неблокирующее параллельное поведение, как и в случае 1 в приложении WPF?

3 ответа

Решение

Спасибо за ответы, ребята. В конце концов, ответ гораздо более гнусный, и я до сих пор не уверен, в чем проблема, но я нашел обходной путь. Основной код выполняет вызовы службы WCF. Использование библиотеки Task Parallel для создания группы параллельных вызовов WCF при первом использовании канала будет сериализовать эти вызовы. По счастливой случайности я обнаружил, что если вы сначала "заправляете" канал одним вызовом, ожидаете ответа, а затем отбрасываете его множеством параллельных вызовов WCF, то вы получаете полный параллелизм. Есть ли менее хакерский, возможно, правильный способ заправить канал WCF как таковой? Это ошибка в WCF или TPL?

Попробуйте следующее:

Await Task.Run(() => 
{
    Parallel.For(0,100, ()=> RetrieveRecordSet<>());
}

Parallel.For действительно блокирующая операция. Если вы хотите, чтобы цикл Parallel.For выполнялся в отдельном потоке, нежели пользовательский интерфейс:

new Thread(() => Parallel.For(0, 100, index => RetrieveRecordSet<TestClass3>())).Start();

Или же

new Task(() => Parallel.For(0, 100, index => RetrieveRecordSet<TestClass3>())).Start();
Другие вопросы по тегам