#c# #parallel.foreach
#c# #parallel.foreach
Вопрос:
Я закодировал запуск более или менее следующей конструкции — и когда ParallelRunner получает функцию делегирования TestFunc, она зависает, однако, если вместо предоставления делегата я пишу функцию явно внутри метода ParallelRunner, она работает нормально.
Обратите внимание, что этот точный метод тестирования работает, но очень похожий код, выполняемый в IIS (в фоновом потоке), завершается сбоем, и как только я удаляю делегат TestFunc и явно записываю его код в ParallelRunner или даже вызываю TestCondition напрямую ( без делегата), он работает нормально.
Есть идеи, что может вызвать это странное поведение?
interface I { }
class A : I { }
class B :I { }
[TestMethod]
public void TestParallelWithDelegate()
{
var list = new List<I>();
for (int i = 0; i < 300000; i )
{
if (i % 2 == 0)
{
list.Add(new A());
}
else
{
list.Add(new B());
}
}
var bag = new ConcurrentBag<I>();
Func<I, bool> testFunc = TestCondition;
ParallelRunner(list,bag,testFunc);
Console.WriteLine($"terminated with delegate bag size = {bag.Count}");
}
private static bool TestCondition(I i)
{
return !(i is A);
}
void ParallelRunner(List<I> list, ConcurrentBag<I> bag, Func<I,bool> testFunc = null)
{
Parallel.ForEach(list, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 3 },
x =>
{
if (testFunc == null || testFunc(x))
{
bag.Add(x);
}
});
}
Комментарии:
1. Возможно, вы теряете свою переменную, хотя я не очень часто работаю с parallel для каждого. Попробуйте это: над вашей параллелью. ForEach, добавьте,
var testFunc2 = testFunc;
а затем измените свой цикл для выполненияtestFunc2
. Имеет ли это значение?2. В реальном коде TestFunc является статическим методом в некотором классе, так как же он мог быть потерян? Я все равно попробую и посмотрю.. Спасибо
3. Я думаю, что это связано с тем, как долго
testFunc
существует переменная, и правильно указывает на ваш статический метод. Возможно, это не ваш случай — вы попробовали мое предложение?4. Да, он зависает.. Я думаю, это может быть связано с тем фактом, что делегат, отправленный как TestFunc, является статическим методом в классе, статический конструктор которого содержит приведенный выше код… Когда я отлаживаю, я вижу, что действительно это работает до определенного момента, но затем останавливается. Интересно, почему этот статический метод находится в пределах области видимости часть времени, а затем останавливается, как вы предлагаете. есть идеи?
5. Если он просто зависает, проверьте это — devblogs.microsoft.com/pfxteam/static-constructor-deadlocks