我使用以下代码在表单加载方法变为可见之前应用延迟(在显示启动画面之后)。我已将表单加载定义为async
:
private async void MainForm_Load(object sender, EventArgs e)
这是MainForm_Load
:
Task startTimer = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
});
await startTimer;
splash.Close();
this.Visible = true;
但我的延迟功能不起作用,我的启动画面立即关闭,我的表格变得可见。我做错了什么?
更新 这是我的表单加载的代码。但我再次删除了一些块,所以我不会让你头疼:
private async void MainForm_Load(object sender, EventArgs e)
{
this.Visible = false;
// Check license
// Load two user controls
Splash splash = new Splash();
splash.Show();
RefreshPostbagFolder();
InitiateGeneralSettings();
InitiateRunSelectFile();
InitiateRunSelectManualCampaignType();
InitiateImageList();
RefreshManageTab();
RefreshProgramLog();
RefreshServiceLog();
await Task.Factory.StartNew(() => { Thread.Sleep(5000); });
//await startTimer;
splash.Close();
this.Visible = true;
this.BringToFront();
}
答案 0 :(得分:2)
这很有趣,我目前没有解释。我确信WinForms的工作方式不仅仅是设置这些属性。但是这个基本的例子确实复制了这个问题:
private async void Form1_Load(object sender, EventArgs e)
{
this.Hide();
await Task.Factory.StartNew(() => { Thread.Sleep(5000); });
this.Show();
}
单步执行调试器中的代码,实际发生的事情并不是等待代码的其余部分,而是Hide()
没有做我们正在做的事情认为。在执行 Form1_Load
之后,实际上不会显示该表单。由于它以异步方式执行,因此用于显示表单的内部组件能够在await
期间执行。但隐藏表格为时已晚。
这显示了承诺:
private async void Form1_Load(object sender, EventArgs e)
{
BeginInvoke(new MethodInvoker(delegate
{
this.Hide();
}));
await Task.Factory.StartNew(() => { Thread.Sleep(5000); });
this.Show();
}
这样做是在组件显示表单后调用Hide()
。但是,表格仍然显示了几分之一秒。所以这不太理想。
这是一段很长的时间,因为我已经用WinForms完成了任何事情(即使那时我做的也不多),所以我不确定如果不加载表单怎么办?所示。但这至少可以解决为什么它不会在你的情况下“等待”的问题。 正在等待,但期间的等待是表单最初显示的时间。因此,在之前隐藏表单无效。
答案 1 :(得分:1)
您的主要表单会在Application.Run
here内自动显示并激活,请注意applicationContext.MainForm.Visible = true
。
一旦执行点从Form.Load
事件处理程序返回到触发事件的代码(在您的情况下,它触及await
内{{}的位置,它就会变为可见1}}),因此异步部分不会影响其可见性。
为避免闪烁,您最初可以将表单显示为最小化并且没有任务栏图标,如下所示:
MainForm_Load
您最初可以在VS表单设计器或using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form {
WindowState = FormWindowState.Minimized,
ShowInTaskbar = false };
form.Shown += delegate
{
Debug.Print("form.Shown");
};
form.Load += async delegate
{
Debug.Print("form.Load");
var splashForm = new Form { Text = "Splash!" };
splashForm.ShowInTaskbar = false;
splashForm.Show();
await Task.Delay(5000);
splashForm.Hide();
form.WindowState = FormWindowState.Normal;
form.ShowInTaskbar = true;
form.Show();
};
Application.Run(form);
}
}
}
构造函数中设置Program.Main
和Form.WindowState
,而不是修改Form.ShowInTaskbar
。
在旁注中,使用MainForm
代替Task.Delay
包裹Thread.Sleep
或Task.Run
。
答案 2 :(得分:-1)
使用async-await
,您应该使用Task.Run
代替Task.Factory.StartNew
:
Task.Run vs Task.Factory.StartNew
有关async-await
的详细信息,请阅读my async-await
curation上的文章。