为什么我的主窗体需要 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.
应该是可行的。
表单将在构造函数完成后的某个时间显示。如果将长 运行 任务排队代码放入构造函数中,则在完成此长 运行 代码之前,表单不会显示。
而是向表单添加一个按钮并为其创建一个点击处理程序。将长 运行 代码放在那里。然后表格会出现,你可以点击按钮。但随后表格将冻结,因为任务排队,我猜。
我肯定遗漏了一些明显的东西,但我只是不明白为什么我的 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.
应该是可行的。表单将在构造函数完成后的某个时间显示。如果将长 运行 任务排队代码放入构造函数中,则在完成此长 运行 代码之前,表单不会显示。 而是向表单添加一个按钮并为其创建一个点击处理程序。将长 运行 代码放在那里。然后表格会出现,你可以点击按钮。但随后表格将冻结,因为任务排队,我猜。