Честно говоря, я немного хромаю, когда дело доходит до потоковой обработки;) Поэтому я прошу немного помочь.Синхронизация подпотока с основной нитью - не такая очевидная проблема
Предположим, у нас есть какой-то контроль, на котором мы можем нарисовать некоторые диаграммы. Существует также метод, который рисует диаграмму этого элемента управления. Проблема заключается в том, что метод построения диаграмм имеет доступ только к одному из полей элемента управления, и нам нужно обновить элемент управления, когда график будет готов.
Итак, давайте предположим, наш контроль выглядит следующим образом:
class ChartingControl : System.Windows.Forms.Control
{
public Canvas canvas;
public void Refresh();
/*
... other fields/methods
*/
}
где Canvas
класс используется для рисования изображения (что-то вроде графика).
Метод построения графиков имеет доступ только к canvas
объекта (мы не можем изменить его), так что это выглядит так:
public static void DrawChart(canvas)
{ /* draw */ }
Этот метод может быть вызван из отдельной нити, фон рабочего и т.д. ... И я необходимо синхронизировать его с основным потоком и вызвать Refresh()
, когда график готов.
Прямо сейчас, когда график будет готов, я установить флаг на холсте объект
public static void DrawChart(canvas)
{ /* draw */
canvas.Tag = true; // chart is ready
}
И у меня есть фон работник работает внутри графиков контроля и прослушивания, если canvas.Tag
поле изменилось, и если да, то он вызывает Refresh()
Но кажется, что мой метод немного грубый, простой в использовании и т. д. Есть ли лучший способ его улучшить?
Ограничения:
- мы не можем изменить Canvas
класс. Единственное, что мы можем использовать это Tag
поле (типа object
- мы можем изменить ChartingControl
класс и метод рисования
. - Там может быть много графиков управления
. - Мы не имеем никакого контроля над тем, как DrawChart
называется Он может вызываться в отдельном потоке, или нет. это называется в другом месте. Все, что мы можем сделать, это создать элемент управления и метод DrawChart и попытаться общаются их как-то
Решение
ОК, я решил это так : in ChartingControl
Я создал ManualResetEvent manualReset
и работника фона.
задний рабочий ждет manualReset
:
void backgroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
manualReset.WaitOne(); // Wait for a chart to be ready
}
и в конце концов вызывает метод Reset()
void backgroundWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
Refresh();
}
я передать manualReset
объект внутри canvas.Tag
и внутри метода рисования, когда диаграмма готов я звоню manualReset.Set();
, чтобы передать сигнал, что график готов.
Метод DrawChart начинает новую тему или вы называете это в другом потоке? –
Я называю это в другом потоке – Gacek