Есть два основных подхода, которые вы можете использовать.Выберите тот, который имеет наибольшее значение в вашей ситуации.Часто нет правильного или неправильного выбора.Они оба могут работать одинаково хорошо во многих ситуациях.У каждого есть свои преимущества и недостатки.Как ни странно, сообщество, кажется, слишком часто упускает из виду этот метод.Я не уверен, почему это действительно так.Недавно я наткнулся на этот вопрос, в котором все рекомендовали подход «толкать», несмотря на то, что это идеальная ситуация для метода «тянуть» (была одна бедная душа, которая пошла против стада и была отвергнута и в конце концов удалила свой ответ, оставивтолько я как одинокий диссидент).
Метод Push
Пусть рабочий поток отправит данные в форму.Вам нужно будет использовать метод ISynchronizeInvoke.Invoke
для этого.Преимущество здесь в том, что по мере поступления каждого элемента данных он будет немедленно добавлен в таблицу.Недостатком является то, что вам приходится использовать дорогостоящую операцию маршалинга, и пользовательский интерфейс может зависнуть, если рабочий поток слишком быстро получает данные.
void WorkerThread()
{
while (true)
{
object data = GetNewData();
yourForm.Invoke(
(Action)(() =>
{
// Add data to your grid here.
}));
}
}
Метод извлечения
Сделайте так, чтобы поток пользовательского интерфейса извлекал данные из рабочего потока.Рабочий поток будет помещать новые элементы данных в общую очередь, а поток пользовательского интерфейса будет периодически удалять эти элементы.Преимущество здесь в том, что вы можете регулировать объем работы, которую каждый поток выполняет независимо.Очередь - это ваш буфер, который будет уменьшаться и увеличиваться по мере уменьшения и увеличения загрузки процессора.Он также отделяет логику рабочего потока от потока пользовательского интерфейса.Недостатком является то, что если ваш поток пользовательского интерфейса не опрашивает достаточно быстро или поддерживать рабочий поток может переполнить очередь.И, конечно же, элементы данных не будут отображаться в реальном времени в вашей сетке.Однако, если вы установите интервал System.Windows.Forms.Timer
достаточно коротким, это не будет проблемой для вас.
private Queue<object> m_Data = new Queue<object>();
private void YourTimer_Tick(object sender, EventArgs args)
{
lock (m_Data)
{
while (m_Data.Count > 0)
{
object data = m_Data.Dequeue();
// Add data to your grid here.
}
}
}
void WorkerThread()
{
while (true)
{
object data = GetNewData();
lock (m_Data)
{
m_Data.Enqueue(data);
}
}
}