2014-12-18 6 views
1

Я делаю многопоточный тестовый пинг-тестер.Основная форма застряла, когда нить делала тест Ping

Итак, я добавил несколько элементов управления ListView ListView и сделал один BackgroundWorkers для каждого элемента. В конце концов, я начал программу, и когда я начал пинговать, элементы управления формы основной формы застряли и не отвечали до конца каждого пинга (включая время просрочки). Вот весь источник. (я разработал форму с GUI Form Designer)

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Drawing; 
using System.Windows.Forms; 
using System.Net.NetworkInformation; 

namespace Multi_Ping_Tester 
{ 
    public partial class frmMain : Form 
    { 
     //List<Thread> pingThreads = new List<Thread>(); 

     private void doPing(object sender, DoWorkEventArgs e) 
     { 
      Ping pingsender = new Ping(); 
      PingReply pingres; 
      int idx = (int)e.Argument; 

      this.Invoke(new MethodInvoker(delegate() 
      { 
       string addr = lvwIPList.Items[idx].Text; 

       //do 
       //{ 
       pingres = pingsender.Send(addr); 

       if (pingres.Status == IPStatus.Success) 
       { 
        lvwIPList.Items[idx].SubItems[1].Text = pingres.RoundtripTime.ToString(); 
        lvwIPList.Items[idx].BackColor = Color.LightGreen; 
       } 
       else 
       { 
        lvwIPList.Items[idx].SubItems[1].Text = "Nein"; 
        lvwIPList.Items[idx].BackColor = Color.LightPink; 
       } 
       //} while(true); 
      })); 
     } 


     List<BackgroundWorker> bgwList = new List<BackgroundWorker>(); 

     private void ResizeCol() 
     { 
      chdIP.Width = (int)((lvwIPList.Width - 6) * 0.8); 
      chdRTT.Width = (int)((lvwIPList.Width - 6) * 0.2); 
     } 
     public frmMain() 
     { 
      InitializeComponent(); 
     } 

     private void frmMain_Load(object sender, EventArgs e) 
     { 
      ResizeCol(); 
     } 

     private void btnAdd_Click(object sender, EventArgs e) 
     { 
      lvwIPList.Items.Add(txtIP.Text); 
      lvwIPList.FindItemWithText(txtIP.Text).SubItems.Add(""); 
     } 

     private void btnPing_Click(object sender, EventArgs e) 
     { 
/*   pingThreads.Clear(); 
      int idx=0; 
*/ 
      bgwList.Clear(); 
      int idx = 0; 

      foreach (ListViewItem i in lvwIPList.Items) 
      { 
       /* 
       pingThreads.Add(new Thread(new ParameterizedThreadStart(doPing))); 
       pingThreads[idx].IsBackground = true; 
       pingThreads[idx].Start(idx); 
       idx++; 
       */ 
       bgwList.Add(new BackgroundWorker()); 
       bgwList[idx].DoWork += new DoWorkEventHandler(doPing); 
       bgwList[idx].RunWorkerAsync(idx); 
       idx++; 
      } 

     } 
    } 
} 

Некоторые комментируемые линии используют темы, но это делает тот же самый результат. Что может быть проблемой?

ответ

0

Поскольку вы вызываете ping.Send внутри this.Invoke, Invoke будет выполнять делегат синхронно в потоке пользовательского интерфейса и, таким образом, он замораживает пользовательский интерфейс.

Вы должны делать это за пределами this.Invoke или использовать await Ping.SendAsync. Конечно, если вы планируете ждать, вам нужно сделать это в методе async. В вашем случае вам понадобится лямбда async.

+0

Спасибо. Как вы сказали, я использовал ping вне Invoke, и он работает так же, как и я. – Kamome

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