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

How to count entries in updated listbox in C#?

我有一个 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() returns 0 而实际上 Listbox1 中有 6 个项目?

您不应在 UI 线程上使用阻塞调用,例如 WaitAll,因为这会导致死锁,更好的替代方法是使用 async-await.

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

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

await 需要 return 一个 TaskTask<T> 的方法,因此 Apple 的 return 值将需要更改为其中之一。您可以使用 Task.Run 向线程池发送任何同步阻塞调用,但是任何 GUI 元素都必须在 Task.Run 委托之外的主线程上访问,该委托将 运行线程池。

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