如何在 C# 中计算更新列表框中的条目
本文关键字:列表 计算 更新 | 更新日期: 2023-09-27 17:57:14
我有一个Windows表单,其中包含一个列表框(Listbox1
),一个标签(label1
)和一个按钮(button1
)。我已将一个单击事件分配给button1
,代码如下:
public void button1_Click(object sender, EventArgs e)
{
label1.Text = "Parsing entries && initializing comms ...";
apples = new Task(Apple);
apples.Start();
Task.WaitAll(apples);
label1.Text = "No. of items: " + Listbox1.Items.Count.ToString();
if (Listbox1.Items.Count >= 2)
{
Listbox1.SetSelected(1, true);
}
}
public void Apple() {
//Send 1st command - 90000
command = "90000";
CommPort com = CommPort.Instance;
if (command.Length > 0)
{
command = ConvertEscapeSequences(command);
com.Send(command);
}
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port
//Send 2nd command - 90001
command = "90001";
if (command.Length > 0)
{
command = ConvertEscapeSequences(command);
com.Send(command);
}
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port
//Send 3rd command - 90002
command = "90002";
if (command.Length > 0)
{
command = ConvertEscapeSequences(command);
com.Send(command);
}
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port
//Send 4th command - 90003
command = "90003";
if (command.Length > 0)
{
command = ConvertEscapeSequences(command);
com.Send(command);
}
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port
//Send 5th command - 90004
command = "90004";
if (command.Length > 0)
{
command = ConvertEscapeSequences(command);
com.Send(command);
}
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port
//Send 6th command - 90005
command = "90005";
if (command.Length > 0)
{
command = ConvertEscapeSequences(command);
com.Send(command);
}
Thread.Sleep(100); //allow 100ms delay for receiving response from serial port
//Listbox1 eventually contains some (~6) entries
}
但是,当我单击button1
时,label1
显示文本No. of items: 0
,尽管Listbox1
实际上包含 6 个项目。为什么代码Listbox1.Items.Count.ToString()
返回 0 而实际上Listbox1
中有 6 个项目?
您不应该在 UI 线程上使用阻塞调用,例如 WaitAll
,因为这可能会导致死锁,更好的选择是使用 async-await
。
这里有一篇关于异步等待最佳实践的好文章。
您只能在async
mehtod 中使用await
,因此您需要进行button1_Click
async
,然后await
调用Apple
。
您await
的方法需要返回Task
或Task<T>
因此Apple
的返回值需要更改为其中之一。您可以使用Task.Run
向线程池发送任何同步阻塞调用,但是必须在将在线程池上运行的Task.Run
委托之外的主线程上访问任何 GUI 元素。
public async void button1_Click(object sender, EventArgs e)
{
label1.Text = "Parsing entries && initializing comms ...";
await Apple();
label1.Text = "No. of items: " + ((Listbox1.Items.Count).ToString());
if (Listbox1.Items.Count >= 2)
{
Listbox1.SetSelected(1, true);
}
}
public async Task Apple()
{
await Task.Run(()=>
{
// serial comms work ...
}
// add items to list here ...
}
如果您的串行通信 api 支持async
,即 SendAsync
,您只需await
SendAsync
调用并使用await Task.Delay(100)
进行异步睡眠,不需要Task.Run
。