Я пытаюсь реализовать цикл Parallel.ForEach для замены старого цикла foreach, но у меня возникают проблемы с обновлением моего пользовательского интерфейса (у меня есть счетчик, показывающий что-то вроде «обработанных файлов x/y»). Я сделал пример Parallel.For для иллюстрации моей проблемы (ярлык не обновляется).C# Parallel.For и обновление пользовательского интерфейса?
using System;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Threading;
namespace FormThreadTest
{
public partial class Form1 : Form
{
private SynchronizationContext m_sync;
private System.Timers.Timer m_timer;
private int m_count;
public Form1()
{
InitializeComponent();
m_sync = SynchronizationContext.Current;
m_count = 0;
m_timer = new System.Timers.Timer();
m_timer.Interval = 1000;
m_timer.AutoReset = true;
m_timer.Elapsed += new System.Timers.ElapsedEventHandler(m_timer_Elapsed);
m_timer.Start();
}
private void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Task.Factory.StartNew(() =>
{
m_sync.Post((o) =>
{
label1.Text = m_count.ToString();
Application.DoEvents();
}, null);
});
}
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() =>
{
Parallel.For(0, 25000000, delegate(int i)
{
m_count = i;
});
});
}
}
}
Если я изменить метод события нажатия кнопки, а также добавить Thread.Sleep(), кажется, чтобы дать время для обновления UI потока, чтобы делать свою работу:
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() =>
{
Parallel.For(0, 25000000, delegate(int i)
{
m_count = i;
Thread.Sleep(10);
});
});
}
не существует никакого способа, избежать сна, или мне нужно его там? кажется, что мой ui не обновит ярлык, если я не сделаю это? который я нахожу странным, так как я могу перемещать окно приложения (оно не блокируется) - так почему бы не заменить ярлык и как я могу изменить свой код, чтобы лучше поддерживать обновления Parallel.For (каждый) и UI?
Ive искал решение, но я не могу найти что-либо (или я, возможно, искал неправильную вещь?).
С уважением Саймон
Я не знаю много об этом, но может ли это быть чем-то связанным с количеством разрешенных потоков? Если Parallel.For забирает их все и не оставляет для захвата события, то это может объяснить поведение. Но я не уверен в этом, поэтому на самом деле это просто дикое предположение, что, надеюсь, вдохновит кого-то, кто знает больше. :) – Chris
Попробуйте положить Application.DoEvents() после установки текста метки. Это позволит другим потокам (в частности, потоку пользовательского интерфейса) получить возможность перерисовать экран – user2712361