2013-04-20 2 views
-3

Я работаю над тем, что вы входите в Linux-устройство с помощью ssh. Затем я хочу отслеживать состояние соединения каждые 5 секунд. Я пытался сделать это с фоновым работником, но у меня было много проблем с кросс-резьбой. Итак, я создал новые потоки вручную и обработал поперечную резьбу с делегированием.Проблемы с многопоточным визуальным C#

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

Это код Логина Я использую:

private void login_button_Click(object sender, EventArgs e) 
    { 
     toolStripProgressBar1.Visible = true; 
     status.Text = "Connecting..."; 
     Thread t = new Thread(check_del_login); 
     t.IsBackground = true; 
     t.Start(); 
    } 
    delegate void del(); 
    private void check_del_login() 
    { 
     if (this.InvokeRequired) 
     { 
      del d = new del(login); 
      Invoke(d); 
     } 
     else 
     { 
      login(); 
     } 
    } 
    private void login() 
    { 
     ssh = new ssh_login(ip_addr, ssh_username, ssh_password); 
     f = new Form3(); 
     f.sftp(ip_addr, ssh_username, ssh_password);// Send the information to the new form 
     try 
     { 
      ssh.login1();//Connect 
      ssh.login2();//Connect 
     } 
     catch (Exception ex) 
     { 
      log(ex); 
     } 
     if (!ssh.check_login1() || !ssh.check_login2()) 
     { 
      MessageBox.Show("Could not login by SSH to " + ip_addr); 
      return; 
     } 
     try 
     { 
      f.login();// Login with sftp 
     } 
     catch (Exception ex) 
     { 
      log(ex); 
     } 
     if (!f.check_connection()) 
     { 
      MessageBox.Show("Could not login by web to " + ip_addr); 
      return; 
     } 
     toolStripProgressBar1.Visible = false;// hide the progress bar when the process finishes 
     if (ssh.check_login1() && ssh.check_login2() && f.check_connection()) 
     { 
      status.Text = "Connected"; 
      connection_status_timer.Start(); 
      status.Text = "Updating interface list..."; 
      Thread t = new Thread(check_del_update_interface); 
      t.IsBackground = true; 
      t.Start(); 
      show_form(); 
      hide_login(); 
     } 
     else 
     { 
      status.Text = "Disconnected"; 
      hide_form(); 
      show_login(); 
      comboBox_interface.Items.Clear(); 
      comboBox_interface.Items.Insert(0, "any"); 
      connection_status_timer.Stop(); 
     } 
    } 

Подходит все направляющий я мог найти он-лайн, но я просто не понимаю, что я делаю неправильно.

Заранее спасибо.

+1

Вы идете не так. Отделите код потока от u-кода. Как можно больше. –

ответ

3

Ваша прямая проблема check_del_login() всегда будет вызывать() основной метод login(). И это означает, что ваш фактический код снова запускается в основном потоке.

private void check_del_login() // is run on a thread 
{ 
    if (this.InvokeRequired)  // always true 
    { 
     del d = new del(login); // so, run login() on Main thread again 
     Invoke(d); 
    } 
    else 
    { 
     login(); 
    } 
} 

Вы должны просто исключить метод Thos и запустить login() на потоке непосредственно. Но тогда вы сталкиваетесь (только первый):

toolStripProgressBar1.Visible = false;// hide the progress bar when the process finishes 

Этот метод касается GUI, поэтому он должен быть вызван. И у вас много похожего кода.

Лучший совет: вернитесь к Фоновому работнику и исправьте свои проблемы с пользовательским интерфейсом.

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