如何在 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 个项目?

如何在 C# 中计算更新列表框中的条目

您不应该在 UI 线程上使用阻塞调用,例如 WaitAll,因为这可能会导致死锁,更好的选择是使用 async-await

这里有一篇关于异步等待最佳实践的好文章。

您只能在async mehtod 中使用await,因此您需要进行button1_Click async,然后await调用Apple

await的方法需要返回TaskTask<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