为什么我的主窗体需要 20 秒以上才能显示?

Why does my main form take 20+ seconds to become visible?

我肯定遗漏了一些明显的东西,但我只是不明白为什么我的 Windows 表单应用程序中的主表单需要 20 秒才能显示出来。我的程序试图采用我在控制台应用程序示例中找到的 TPL 代码示例,并在 windows form/gui 中运行。我知道任务排队需要 20 秒才能完成,但是那段代码是否发生得如此之快以至于表单没有时间完成初始化?我尝试在 "InitializeComponent();" 之后立即延迟,希望它能给表单时间来完成;并且还尝试在之后仅放置一个消息框,但在我插入延迟后仍然会出现相同的延迟。没有 form_load 方法,所以没有什么可检查的。

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();

        // Time the test(s) 
        Stopwatch stoppwatch = new Stopwatch();
        stoppwatch.Start();

        Console.SetOut(new ControlWriter(tb1)); // just redirects console.writeline to the form's textbox "tb1"

        // #################################### job queue ########################################
        var q = new TPLDataflowMultipleHandlers();  //
        var numbers = Enumerable.Range(1, 10);

        foreach (var num in numbers)
        {
            F1TimeDelay(2);
            q.Enqueue(num.ToString());
        }

        // Stop the timer and return the elapsed number of milliseconds.
        stoppwatch.Stop();
        Console.WriteLine("XXXXXXXXXX  <STATUS> Elapsed time = {0} minutes. XXXXXXXXXX", (int)stoppwatch.Elapsed.TotalMinutes);
    }

顺便说一句,当表单最终出现时,文本框充满了我期望从已启动的线程中看到的消息(线程 ID 等信息)。

F1TimeDelay(2) 是 2 秒的延迟,而排队的作业只是 10 秒长的任务,以并行演示 10 个任务 运行。发送到队列的数字最终成为 10 个任务的作业编号。

因为在构造函数和 FormShown 事件之间的某处,您正在调用需要 20 多秒才能完成的代码。

虽然我在构造函数中看不到任何内容,但这显然只是加载过程的开始:https://docs.microsoft.com/en-us/dotnet/framework/winforms/order-of-events-in-windows-forms

通常,您最早应该检索任何数据或执行任何其他操作的时间是在 Shown 事件中。即使这样,像这样的长 运行 操作也应该通过某种形式的 Multitasking/Asynchronous 操作来完成。您必须弄清楚它是什么,但我的猜测是磁盘或 Network/Database 访问权限。

如果你想做测量希望正确,你需要在Constructor中启动StopWatch,并且只stop/show在Shown中显示结果。即使这样,您的 Shown Event 也可能是第一个被调用的 hard/long 工作,因此它可能会错过导致问题的任何原因。您的秒表也不包含 Designer 创建的元素。 Designer 代码使用 InitializeComponents() 执行。当然,在这样一个数量级的延迟下,只输出 DateTime.Now regulary.

应该是可行的。

表单将在构造函数完成后的某个时间显示。如果将长 运行 任务排队代码放入构造函数中,则在完成此长 运行 代码之前,表单不会显示。 而是向表单添加一个按钮并为其创建一个点击处理程序。将长 运行 代码放在那里。然后表格会出现,你可以点击按钮。但随后表格将冻结,因为任务排队,我猜。