Я пытаюсь реализовать цикл Parallel.ForEach, чтобы заменить старый цикл foreach
, но у меня возникают проблемы с обновлением пользовательского интерфейса (у меня есть счетчик, показывающий что-то вроде «обработанные файлы x / y»).Я сделал Parallel Forloop
пример, чтобы проиллюстрировать мою проблему (метка не обновляется).
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 (), он кажетсячтобы дать время потоку обновления пользовательского интерфейса выполнить свою работу:
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() =>
{
Parallel.For(0, 25000000, delegate(int i)
{
m_count = i;
Thread.Sleep(10);
});
});
}
Нет ли способа избежать сна или мне нужно иметь его там?кажется, что мой интерфейс не будет обновлять лейбл, если я не сделаю?что мне кажется странным, так как я могу переместить окно приложения (оно не блокируется) - так почему бы не обновить ярлык, и как я могу изменить свой код, чтобы лучше поддерживать обновления Parallel.For (Each) и UI?
Я искал решение, но мне кажется, что я ничего не могу найти (или, может, я искал не то?).
С уважением, Саймон