Задачи выполняются последовательно по какой-то причине
Случай 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();