所以我正在尝试从我通过本地网络接收的一些数据中更新列表框。
我知道我缺少一些基本的东西。谁能解释一下我在这里做错了什么?我意识到你不能从UI线程以外的任何线程更新UI。我想我的问题是我不知道如何指定我希望UI线程更新值。
您可以在监视器主题中看到我想要完成的任务。
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 :(得分:0)
使用非UI线程中的BeginInvoke。
Action<string> add = str => {
lbStudents.Items.Add(str);
}
BeginInvoke(add, data);