Как обнаружить недействительный элемент управления? - PullRequest
2 голосов
/ 14 мая 2011

Я реализую проблему производителя / потребителя. код выглядит так:

void producer()
{
  // produce item
  // update some control in form
}

void consumer()
{
  // consume item
  // update some control in form
}

Методы производителя и потребителя выполняются в потоках, отличных от тех, что создали мою форму, поэтому я не могу обновить элементы управления в форме. Я попробовал следующий код:

void producer()
{
  // produce item
  // put the work to be done in a queue
  this.Invalidate();
}

void consumer()
{
  // consume item
  // put the work to be done in a queue
  this.Invalidate();
}

Так что теперь я должен определить, была ли форма недействительной. Я посмотрел в списке событий Form, и лучшее, что я смог найти, это событие Paint. Я поместил код, который сделал работу, и она работает нормально. Проблема в том, что я почему-то сомневаюсь, что сделал все правильно, хотя это работает. Я думаю, что краска - это не то место, где нужно делать работу, потому что я занимаюсь не просто рисованием. Мне было интересно, есть ли лучший способ сделать это.

Редактировать - фрагмент кода для обработчика недействительных событий не работает

public Form1()
{
  InitializeComponent();
  this.Invalidated += InvalidateEventHandler;
}
void producer(object o)
{
  // produce
  // put work in queue
  this.Invalidate();
}
public void InvalidateEventHandler(object sender, InvalidateEventArgs e)
{
  // Do Stuff to form -- Where exception raises
}

Ответы [ 2 ]

4 голосов
/ 14 мая 2011

Invalidate предназначен для запуска Paint.

Вам нужно Control.Invoke() свой собственный метод обновления в форме.

Edit:

Ваши потоки, не относящиеся к GUI, даже не должны вызывать Invalidate (), они не могут касаться GUI.

Вы можете написать свой собственный метод-форму ProcessData () и из вызова Prod / Cons mainForm.Invoke(ProcessData)

Тогда ProcessData() отвечает за потокобезопасный доступ к данным и за аннулирование GUI

1 голос
/ 14 мая 2011

Вы можете попытаться использовать ключевое слово new, чтобы создать собственную реализацию Invalidate

    public new void Invalidate()
    {
        // place your logic here
        base.Invalidate();
    }

В форме также есть Invalidated событие, которое запускается после Ivalidateзаканчивается

РЕДАКТИРОВАТЬ:

public void InvalidateEventHandler(object sender, InvalidateEventArgs e)
{
    anotherForm.Invoke(new Action(() =>
    {
        // Do Stuff to form -- Where exception raises
    }));
}
...