2016-03-09 5 views
0

Итак, я пытаюсь обновить список из некоторых данных, которые я получаю через свою локальную сеть.Обновление списка из отдельного потока C#

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

Вы можете видеть в потоке монитора то, что я пытаюсь выполнить.

namespace FrontEnd 
{ 
    public partial class Form1 : Form 
    { 
     TcpClient clientSocket = new TcpClient(); 
     //CommandQueue commandqueue; 
     private List<String> COMMANDS = new List<String>(); 
     private object m_lock = new object(); 
     delegate void AddListItemDelegate(string text); 

     public void enqueue(string command) 
     { 
      lock (m_lock) 
      { 
       Debug.WriteLine("Enqueue"); 
       COMMANDS.Add(command); 
      } 
     } 

     public string dequeue() 
     { 
      lock (m_lock) 
      { 
       string tmp = COMMANDS.First(); 
       COMMANDS.RemoveAt(0); 
       return tmp; 
      } 
     } 


     public void monitor() 
     { // need a better mechanism 

      while (true) 
      { // bad algorithm 
       lock (m_lock) 
       { 
        if (COMMANDS.ToArray().Length > 0) 
        { // if queue is not empty 
         do 
         { // this is okay 
          string dequeued = dequeue(); 
          string command = dequeued.Split(':')[0]; 
          string data = dequeued.Split(':')[1]; 
          if (command.Equals("add")) 
          { // add student 
           Debug.WriteLine("adding item to listbox"); 

           //lbStudents.Items.Add(data); 
           //lbStudents.Update(); 
          } 
         } while (COMMANDS.ToArray().Length > 0); 
        } 
       } 
      } 
     } 

     public Form1() 
     { 
      InitializeComponent(); 
     } 
     public void launchThread() 
     { 

      Form1 f1 = new Form1(); 
         Thread oThread = new Thread(monitor); 
      oThread.Start(f1); 
      while (!oThread.IsAlive) ; 
      Debug.WriteLine("THREAD LAUNCHED"); 
     } 

     private void cleanResponse(string response) 
     { 
      string[] responses = response.Split(':'); 
      string command = responses[0]; 
      string[] data = responses.ToList().GetRange(1, responses.Length - 2).ToArray(); 
      for (int i=0;i<data.Length;i++) 
      { 
       Debug.WriteLine("thing in here debug"); 
       try 
       { 
        enqueue(command + ':' + data[i]); 
       } 
       catch (Exception e) 
       { 
        Debug.WriteLine("EXCEPTION: " + e); 
       } 
      } 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      launchThread(); 
      lblStatus.Text = "Connecting..."; 
      clientSocket.Connect("10.108.45.120", 9001); 
      Stream stm = clientSocket.GetStream(); 
      byte[] ba = new ASCIIEncoding().GetBytes("start"); 
      stm.Write(ba, 0, ba.Length); 
      byte[] bb = new byte[100]; 
      lblStatus.Text = "Connected!"; 
      stm.Read(bb, 0, bb.Length); 
      string response = System.Text.ASCIIEncoding.UTF8.GetString(bb); 
      cleanResponse(response); 
      clientSocket.Close(); 
      grpbxSparseMatrix.ForeColor = Color.White; 
     } 
    } 
} 
+0

Именно поэтому они создали BackGroundWorker, так что вы не сломаете себе голову, как правильно вводить в себя потоки –

ответ

0

Использование BeginInvoke из потока, отличного от UI.

Action<string> add = str => { 
    lbStudents.Items.Add(str); 
} 

BeginInvoke(add, data); 
+0

Спасибо за помощь! – wookieluvr