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 Execution Order

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 和线程东西的学习者,所以如果我错了,请纠正我!