2015-12-31 5 views
1

Я знаю, что есть много вещей о замораживающих формах foreach, но я не могу найти решение моей проблемы. У меня уже есть часть сервера этой программы работает Я пытаюсь сделать на сторону клиента, что при подключении к серверу, этот код будет отформованным txtConn.AppendText("Attempting connection.");Замораживающая форма Foreach

Это код, который я для подключения розетки

private static Socket ConnectSocket(string server, int port, RichTextBox txtConn, BackgroundWorker backgroundWorker1) 
    { 
     Socket s = null; 
     IPHostEntry hostEntry = null; 

     // Get host related information. 
     hostEntry = Dns.GetHostEntry(server); 

     // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid 
     // an exception that occurs when the host IP Address is not compatible with the address family 
     // (typical in the IPv6 case). 
     backgroundWorker1.RunWorkerAsync(); 
     foreach (IPAddress address in hostEntry.AddressList) 
     { 
      IPEndPoint ipe = new IPEndPoint(address, port); 
      Socket tempSocket = 
       new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
      Console.WriteLine(ipe); 
      try 
      { 
       attempt++; 
       txtConn.Select(txtConn.TextLength, 0); 
       txtConn.SelectionColor = Color.Aqua; 
       if (attempt == 1) 
       { 
        txtConn.AppendText("Attempting connection."); 
       } 
       else if (attempt > 1) 
       { 
        txtConn.AppendText("\r" + "Attempting connection."); 
       } 
       txtConn.SelectionColor = txtConn.ForeColor; 
       tempSocket.Connect(ipe); 
      } 
      catch (ArgumentNullException ane) 
      { 
       Console.WriteLine("ArgumentNullException : {0}", ane.ToString()); 
       txtConn.Select(txtConn.TextLength, 0); 
       txtConn.SelectionColor = Color.Red; 
       txtConn.AppendText("\r\n" + "Connection could not be established."); 
       txtConn.SelectionColor = txtConn.ForeColor; 
      } 
      catch (SocketException se) 
      { 
       Console.WriteLine("SocketException : {0}", se.ToString()); 
       txtConn.Select(txtConn.TextLength, 0); 
       txtConn.SelectionColor = Color.Red; 
       txtConn.AppendText("\r\n" + "Connection could not be established."); 
       txtConn.SelectionColor = txtConn.ForeColor; 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Unexpected exception : {0}", e.ToString()); 
       txtConn.Select(txtConn.TextLength, 0); 
       txtConn.SelectionColor = Color.Red; 
       txtConn.AppendText("\r\n" + "Connection could not be established."); 
       txtConn.SelectionColor = txtConn.ForeColor; 
      } 

      if (tempSocket.Connected) 
      { 
       Console.WriteLine("Connected"); 
       s = tempSocket; 
       break; 
      } 
      else 
      { 
       continue; 
      } 
     } 
     return s; 
    } 

My program looks like this

Когда я запускаю программу и соединиться с сказать неправильный порт, он проверяет все возможные IP-адреса на моем компьютере и ждет, пока после того, как оператор Еогеасп для отображения ошибок или что-нибудь. Как я могу заставить его активно отображать это? This is when it runs

+0

* foreach заморозки формы *? Вы говорите о том, что программа становится невосприимчивой? Похоже, вам нужно прочитать о 'Thread's. –

+0

Я вижу, что у вас уже есть рабочий фон. Какой код он выполняет? Почему бы вам не поставить цикл for внутри фонового обработчика событий DoWork? –

ответ

0

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

Самый простой способ сделать это - добавить цикл соединения к новой задаче в ThreadPool.

ThreadPool.QueueUserWorkItem(i => { 
    // Connection loop goes here. 
}); 

Если вам нужно other options вы можете также использовать Task, BackgroundWorker и т.д.

0

Использование должны использовать Async методы из Socket класса или запустить этот материал в другом потоке. Вы можете использовать BackgroundWorker, чтобы сделать это.

0

Я только что ответил на аналогичный вопрос here, но чтобы развернуть его для вашего конкретного случая, похоже, что вы фактически не используете backgroundWorker1. Предпросмотр должен выполняться в методе, на который ссылается событие backgroundWorker1.DoWork. Вам также необходимо создать метод для события backgroundWorker1.ProgressChanged. Вы можете использовать ReportProgress, чтобы передать строку, а затем добавить, что сообщение на текстовое поле:

Из вашего цикла Еогеаспа в методе Worker_DoWork, вы будете сообщать о прогрессе вместо обновления RichTextBox непосредственно:

worker.ReportProgress(0, "Connection could not be established."); 

А потом в методе Worker_ProgressChanged, вы будете использовать что-то вроде этого, чтобы обновить RichTextBox:

txtConn.AppendText(e.UserState.ToString()); 
+0

Как добавить строку в richtextbox? – MattG5TK

+0

В вашем цикле foreach вы будете называть worker.ReportProgress с сообщением, а не напрямую обновлять RichTextBox. Итак, в методе Worker_ProgressChanged вы сделаете что-то вроде txtConn.AppendText (e.UserState.ToString()). Я обновлю ответ, чтобы это отразить. – Tim

+0

Спасибо, что это помогло больше всего. Спасибо Тиму. – MattG5TK

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