2013-10-15 2 views
1

У меня есть делегат Action:DataGridView.Invoke замерзает

public static Action SubscribeForTable; 

Я загрузил его с моим Objects методом

public void SubscribeMe() 
{ 
    Parallel.For(0, ACCESS.GetAppCount(), AppCheck); 
    CheckTable(true); 
} 

Так что я есть делегат, который содержит ту же самую функцию, но и для различных объектов.

Тогда я делаю это:

Parallel.Invoke(SubscribeForTable); 

Так он начал работать, и я жду ... жду ... и ничего не происходит! Приложение застряло! Затем я начал свой отладчик.

SubscribeMe() возвращение к функции

Parallel.For(0, ACCESS.GetAppCount(), AppCheck); //OK 
CheckTable(true); // lets see what is in 

Потом я посмотрел на эту функцию ..

delegate void CheckTableCallback(bool check); 

private void CheckTable(bool Subscribed) 
{ 
    if (DataGridView1.InvokeRequired) // OK 
    { 
     CheckTableCallback Safe = new CheckTableCallback(CheckTable); // OK 
     DataGridView1.Invoke(Safe, new Object[] {Subscribed}); //HANGS HERE! 
    } 
    else 
    { 
     .... 

Так он висит на DataGridView.Invoke. Почему так? Надеюсь, я правильно объяснил свою проблему.

+1

Использование Invoke() может вызвать взаимоблокировку, всегда благоприятствует BeginInvoke(). Этот тупик вызван тем, что поток пользовательского интерфейса занят, обычно ожидая завершения рабочего потока. Он не должен ждать. Используйте Debug + Windows + Threads для отладки. –

ответ

2

Control.Invoke, по конструкции, блокирует текущий поток, пока поток пользовательского интерфейса не сможет обрабатывать сообщения.

Если вы вызываете свой цикл Parallel.For из потока пользовательского интерфейса, который будет блокировать поток пользовательского интерфейса до его завершения.

Эти две причины приводят к тому, что одна операция (вызов Invoke) не может быть завершена до тех пор, пока другой не завершит и не освободит поток пользовательского интерфейса (Parallel.For), но второй не может завершить работу до тех пор, пока отдельные рабочие элементы не закончатся.

Возможно, вы используете BeginInvoke вместо Invoke, чтобы избежать блокировки здесь, если вы просто обновляете пользовательский интерфейс. Это приведет к запуску фактического метода (CheckTable) и установки значений после завершена вся операция.

+0

похоже, что работает 'BeginInvoke', спасибо! –

Смежные вопросы