如何计算 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 一个 Task
或 Task<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
。
我有一个 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 一个 Task
或 Task<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
。