Я запускаю цикл Parallel.For для немногим более 7500 объектов.Внутри цикла for я делаю несколько вещей для каждого из этих объектов, в частности, вызываю два веб-сервиса и два внутренних метода.Веб-сервисы просто проверяют объект, обрабатывают и возвращают строку, которую я затем устанавливаю как свойство объекта.То же самое касается двух внутренних методов.
Я ничего не записываю на диск или не читаю с диска.
Я также обновляю пользовательский интерфейс в приложении winforms с меткой и индикатором выполнения, чтобысообщите пользователю, где он находится.Вот код:
var task = Task.Factory.StartNew(() =>
{
Parallel.For(0, upperLimit, (i, loopState) =>
{
if (cancellationToken.IsCancellationRequested)
loopState.Stop();
lblProgressBar.Invoke(
(Action)
(() => lblProgressBar.Text = string.Format("Processing record {0} of {1}.", (progressCounter++), upperLimit)));
progByStep.Invoke(
(Action)
(() => progByStep.Value = (progressCounter - 1)));
CallSvc1(entity[i]);
Conversion1(entity[i]);
CallSvc2(entity[i]);
Conversion2(entity[i]);
});
}, cancellationToken);
Это происходит на 32-битной машине Win7.
Любые идеи относительно того, почему это внезапно замирает, когда инкрементатор составляет около 1370 или около того (это было 1361,1365 и 1371)?
Любые идеи относительно того, как я могу отладить это и посмотреть, что блокирует, если что-нибудь?
РЕДАКТИРОВАТЬ:
Некоторые ответы на комментарии ниже:
@BrokenGlass - Нет, взаимодействия нет.Я попробую компиляцию x86 и сообщу вам.
@ chibacity - поскольку это фоновая задача, она не замораживает пользовательский интерфейс.Вплоть до того момента, пока он не замерзнет, индикатор выполнения и метка будут показывать примерно 2 каждую секунду.Когда он замерзает, он просто перестает двигаться.Я могу убедиться, что число, на котором он останавливается, было обработано, но не более.Использование процессора на двухъядерном процессоре 2,2 ГГц минимально во время работы: 3-4% каждый и 1-2% после его зависания.
@ Хенк Холтерман - до 1360 и около 10-12 минутда, я могу проверить, что все эти записи были обработаны, но не остальные записи.
@ CodeInChaos - Спасибо, я попробую!Код работает, если я уберу параллель, это займет вечность и день.Я не пробовал ограничивать количество потоков, но сделаю это.
РЕДАКТИРОВАТЬ 2:
Некоторые подробности о том, что происходит с веб-сервисами
В основном, чтоВеб-сервисы продолжают передавать некоторые данные и получать данные (XmlNode).Этот узел затем используется в процессе Conversion1, который, в свою очередь, устанавливает другое свойство объекта, которое отправляется в метод CallSvc2 и так далее.Это выглядит так:
private void CallSvc1(Entity entity)
{
var svc = new MyWebService();
var node = svc.CallMethod(entity.SomeProperty);
entity.FieldToUpdate1.LoadXml(node.InnerXml);
}
private void Conversion1(Entity entity)
{
// Do some xml inspection/conversion stuff
if (entity.FieldToUpdate1.SelectSingleNode("SomeNode") == "something") {
entity.FieldToUpdate2 = SomethingThatWasConverted;
}
else {
// Do some more logic
}
}
private void CallSvc2(Entity entity)
{
var svc = new SomeOtherWebService();
var xmlNode = svc.MethodToCall(entity.FieldToUpdate2.InnerXml);
entity.AnotherXmlDocument.LoadXml(xmlNode.InnerXml);
}
Как видите, это довольно просто.В некоторых методах преобразования много чего происходит, но ни один из них не должен блокировать.И, как отмечено ниже, 1024 потока находятся в состоянии «ожидания», и все они находятся на вызовах веб-службы.Я прочитал здесь http://www.albahari.com/threading/, что MaxThreads по умолчанию установлен на 1023 для .Net 4 на 32-битной машине.
Как мне освободить эти ожидающие темы, учитывая то, что у меня здесь?