2015-01-07 2 views
0

Я эту ситуацию:C# Threading и модернизация GUI

Форма «Меню», где вы можете нажать кнопку «Создать» и форму вставки (с ShowDialog) появится. Если вы вставляете данные, я делаю запрос INSERT в базе данных, и я закрываю эту форму. После оператора showDialog() у меня есть много методов, которые выполняют много операций последовательным образом (MUCH WAV) и иногда обновляют dataGridView. После всего этого вычисления я имитирую нажатие «новой кнопки», чтобы пользователь мог вставить новый элемент. Это пример:

private void buttonNew_Click(object sender, EventArgs e) 
{ 
     DialogResult dr = new DialogResult(); 
     InsertForm form = new InsertForm(); 
     dr = form.ShowDialog(); 

     if (dr == System.Windows.Forms.DialogResult.OK) 
     { 
      Method1(); 
      Method2(); 
      if (dataGrid2.RowCount > 0) 
      { 
       Method3(); 
       Method4(); 
       Method5(); 
       Method6(); 
       Method7(); 
       Method8(); 
      } 
      bNew.PerformClick(); 
     } 
} 

Проблема заключается в том, что «Новая» форма (bNew.PerfomClick()) появляются через 2-3 секунды, и я не могу ждать столько времени. Поэтому я попытался создать метод, который включает Method1 в Method8, запустить его в новом потоке и выполнить bNew.PerfomClick(), но это не работает, потому что многие мои методы обновляют datagridView.

Есть ли способ решить эту проблему? Извините за мой плохой английский.

------------ UPDATE ------------------

Теперь я пытаюсь этот код:

delegate string OperazioniDelegate(); 

    private string Operazioni() 
    { 
     if (!InvokeRequired) 
     { 
      Method1(); 
      Method2(); 
      ............ 
     } 
     else 
      Invoke(new OperazioniDelegate(Operazioni)); 
     return ""; 
    } 

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Operazioni(); 
    } 

Таким образом, новая форма вставки предъявляются мгновенно, но его интерфейс блокируется до работы BackgroundWorker End ..

+0

Возможный дубликат: http://stackoverflow.com/questions/661561/how-to-update-the-gui-from-another-thread-in-c?rq= 1 – Onots

+0

Привет, проблема в том, что мне нужно не только обновлять пользовательский интерфейс, но мне также нужно выполнить много операций в другом потоке и обновить NEXT ui .. – helloimyourmind

ответ

0

Предполагая, что вы используете свою длительную работу, которая выполняется в отдельном потоке, который обновляет элементы пользовательского интерфейса (DataGridView в вашем случае), он должен испытывать исключение перекрестного потока, поскольку контекст, в котором выполняется фоновый поток, отличается от m, что и в потоке пользовательского интерфейса. Либо использовать InvokeRequired, как указано ниже:

delegate void valueDelegate(string value); 

    private void SetValue(string value) 
    { 
     if (someControl.InvokeRequired) 
     { 
      someControl.Invoke(new valueDelegate(SetValue),value); 
     } 
     else 
     { 
      someControl.Text = value; 
     } 
    } 

или использовать BackgroundWorker класс, который будет делать автоматический маршалинг вызовов от фонового потока до Ui нити. Использование справочного работника приводится по этой ссылке http://www.albahari.com/threading/part3.aspx#_BackgroundWorker

+0

Так что мне нужно выполнять методы в отдельных потоках каждый из одного вызова «valueDelegate», когда им нужно обновить интерфейс? – helloimyourmind

+0

Да, вам нужно запустить свою длительную операцию в отдельном потоке. Но каждый из них не требует вызова invoke. Этот код должен быть рядом с кодом UI, например, в классе Form. Я бы предпочел использовать BackGroundWorker, так как он будет автоматически выполнять маршалинг, и вы также будете иметь контроль над работой, например, получить ход операции или отменить операцию. – Giri

+0

Можете ли вы посмотреть мое обновление? – helloimyourmind