Control.BeginInvoke Execution Order
本文关键字:Order Execution BeginInvoke Control | 更新日期: 2023-09-27 18:36:39
调用 BeginInvoke() 时,委托会以调用该方法的顺序返回吗? 还是不能保证哪些代表会先回来?
public Form1()
{
InitializeComponent();
for (int i = 0; i < 100; i++)
{
Thread t = new Thread(DisplayCount);
t.Start(i);
}
}
public void DisplayCount(object count)
{
if (InvokeRequired)
{
BeginInvoke(new Action<object>(DisplayCount), count);
return;
}
listBox1.Items.Add(count);
}
整数列表将无序返回。
Control.BeginInvoke()
将在 UI 线程上异步执行操作。
如果您使用不同的操作多次调用BeginInvoke()
,它们将按完成最快的顺序返回。
作为旁注,您可能应该在listBox1.Items.Add(count)
调用周围使用某种 snychage 化机制,也许会锁定其SynchRoot
属性。
来自 MSDN - ListBox.ObjectCollection Class
此类型的任何公共静态(在 Visual Basic 中共享)成员都是 线程安全。不保证任何实例成员都是线程 安全。
(着重号后加)
如果您多次调用相同的函数,那么它们应该以相同的顺序返回,也许!如果您有一个分析1 TB数据集的函数和另一个只是执行一些日志记录的函数,那么我认为它们不会以相同的顺序返回。它还取决于您为 BeginInvoke 设置的调度程序优先级。像 SystemIdl
这样的低优先级将在稍后执行,然后像 Send
这样的高优先级执行。
如果使用Thread.Start()
启动线程,则线程函数的执行在该调用后的随机时间异步发生。这就是为什么在我看来你会得到随机数。
我可能是错的,但 Control.BeginInvoke() 将保留排队任务的顺序,只要所有执行都在同一线程上处理,基于此讨论。在 UI 线程建立并处于活动状态后,重新排序的数字实际上反映了它们的排队顺序。换句话说,罪魁祸首是 Thread.Start(),它不能保证顺序。官方文件的评论应该给出一个提示:
一旦线程处于 ThreadState.Running 状态,操作系统就可以计划它执行。线程在提供给线程构造函数的 ThreadStart 或 ParameterizedThreadStart 委托所表示的方法的第一行开始执行。请注意,对 Start 的调用不会阻止调用线程。
我也是一个有 UI 和线程东西的学习者,所以如果我错了,请纠正我!