Я начал с попытки добавить индикатор выполнения в форму окна, которая обновляет ход кода, выполняющегося в цикле Parallel.Foreach. Для этого необходимо, чтобы поток пользовательского интерфейса был доступен для обновления индикатора выполнения. Я использовал задачу для запуска цикла Parallel.Foreach, чтобы позволить потоку пользовательского интерфейса обновлять индикатор выполнения.Использование задачи с Parallel.Foreach в .NET 4.0
Работа выполнена в рамках параллельного цикла. Форекс довольно интенсивный. После запуска исполняемых программ (не отладки в визуальной студии) с помощью Задачи программа перестала отвечать на запросы. Это не тот случай, если я запускаю свою программу без Task. Ключевое различие, которое я заметил между двумя экземплярами, заключается в том, что программа занимает ~ 80% от процессора, когда бегает без Task, и ~ 5% при запуске с помощью Task.
private void btnGenerate_Click(object sender, EventArgs e)
{
var list = GenerateList();
int value = 0;
var progressLock = new object();
progressBar1.Maximum = list.Count();
Task t = new Task(() => Parallel.ForEach (list, item =>
{
DoWork();
lock (progressLock)
{
value += 1;
}
}));
t.Start();
while (!t.IsCompleted)
{
progressBar1.Value = value;
Thread.Sleep (100);
}
}
Side Примечание: Я знаю, что
Interlocked.Increment(ref int___);
работы на месте замка. Считается ли это более эффективным?
Мой вопрос в три раза:
1.) Почему программа с Task зависать, когда нагрузка намного меньше?
2.) Использует ли Task для запуска Parallel.Foreach ограничивает пул потоков Parallel.Foreach только потоком, выполняющим задачу?
3.) Есть ли способ заставить пользовательский интерфейс реагировать вместо спящего для продолжительности .1 секунды без использования токена отмены?
Я благодарен за любую помощь или идеи, я потратил немало времени на изучение этого. Я также извиняюсь, если я нарушил какой-либо формат публикации или правила. Я пытался придерживаться их, но, возможно, что-то пропустил.
Ожидание выполнения задачи в цикле в потоке пользовательского интерфейса подобно выполнению его в потоке пользовательского интерфейса (немного хуже, даже). Посмотрите на «BackgroundWorker» или «async» – SimpleVar
Если 'DoWork()' обращается к любому из ваших элементов интерфейса, это приведет к возникновению тупика. –
JohnathonSullinger - DoWork() не имеет доступа к элементам пользовательского интерфейса. @Yorye Nathan - Не могли бы вы рассказать или привести пример? Я никогда не делал ничего с многопоточным до сегодняшнего дня. –