表单上的睡眠任务加载不起作用

时间:2015-03-03 16:20:30

标签: c# winforms parallel-processing async-await task

我使用以下代码在表单加载方法变为可见之前应用延迟(在显示启动画面之后)。我已将表单加载定义为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();
}

3 个答案:

答案 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.MainForm.WindowState,而不是修改Form.ShowInTaskbar

在旁注中,使用MainForm代替Task.Delay包裹Thread.SleepTask.Run

答案 2 :(得分:-1)

使用async-await,您应该使用Task.Run代替Task.Factory.StartNew

Task.Run vs Task.Factory.StartNew

有关async-await的详细信息,请阅读my async-await curation上的文章。