当进程在当前表单上时如何显示表单

时间:2012-01-20 06:37:21

标签: c# winforms concurrency wait async-await

我在visual studio 2008 framework 3.5中有一个Windows应用程序, 我需要并发等待窗口,在窗口中进行进程,在该窗口上出现另一个表单,其中包含一些动态图像(动画),就像.gif图像一样。

我有两个表单,在form2上,点击按钮我执行一个冗长的过程, 我想要我的' frmWait'当form2上的进程正在进行时显示在屏幕上,并在完成时消失。当我的朋友在'出现,然后表单2不应该被用户访问。

我的代码在这里。 表格2

在SomeWork过程中有一个我写过的for循环,但实际上在程序中它是在sqlserver中执行的数据库命令,当在服务器上执行查询时,我的主程序工作停止直到服务器完成工作,之后程序获得exectution指针,同时,软件似乎被挂了。

    namespace WindowsFormsApplication1
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }

            private void button1_Click(object sender, EventArgs e)
            {
                frmWait fw = new frmWait("Wait...",0);
                fw.Show();

                SomeWork();

                fw.Close();
            }

            private void SomeWork()
            {
                for (int x = 0; x < 99999999; x++)
                { }
            }
        }
    }

6 个答案:

答案 0 :(得分:3)

您应该在后台线程中执行冗长的过程。使用BackgroundWorker即可轻松实现这一目标。

工作人员启动后,只需使用frmWait.ShowDialog()显示frmWait。

当工作人员通知作业结束时,请关闭frmWait,例如使用frmWait.DialogResult=Cancel

您可以利用ProgressChanged事件来报告您的进展情况。

如果用户点击frmWait中的“取消”按钮,只需在后台工作人员上调用CancelAsync()即可。

Full sample here

答案 1 :(得分:2)

.NET 4引入了任务并行库,这使得这样的任务变得更容易。您应该使用 System.Threading.Tasks.Task而不是使用BackgroundWorker。这个问题的答案中有更多信息:Task parallel library replacement for BackgroundWorker?

答案 2 :(得分:2)

首先添加..

using System.Threading;

我已修改上面的代码以使用单独的帖子..

private void button1_Click(object sender, EventArgs e) 
{ 
    this.SomeWork();             
}

Thread t;

private void SomeWork()
{
    frmWait fw = new frmWait("Wait...", 0);

    this.t = new Thread((ThreadStart)delegate()
    {

        for (int x = 0; x < 99999; x++)
        {
            Thread.Sleep(100);

            //Debug.WriteLine(x);
        }


        if (this != null && !this.IsDisposed) this.BeginInvoke((ThreadStart)delegate() { fw.Close(); });
    });

    this.t.Start();

    fw.ShowDialog(this);
}

如果允许用户在完成之前关闭Form2,您也可能想要处理FormClosing事件以终止线程!

private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
    if (t != null && t.IsAlive) t.Abort();
} 

答案 3 :(得分:0)

您应该在此方案中使用BackgroundWorkerSomeWork部分移离主UI线程

SomeWork();部分移至DoWork的单独BackgroundWorker方法。这样SomeWork将由BackgroundWorker在单独的后台线程中执行。然后在Background Work Completed完成SomeWork完成后fw.Close();事件{{1}}

答案 4 :(得分:-1)

您可以使用模态拨号框。因为它不允许与其他形式(即表格2)互动

frmWait.ShowDialog();

还尝试使用Backgroud worker background worker,这样可以更轻松地进行后台处理。

答案 5 :(得分:-1)

我不明白你的意思,但是如果你想要这个,直到frmWait打开,你的Form2一定不能被用户访问,使用frmWait.ShowDialog(),如果你想在特定进程时关闭frmWait结束,在frmWait中,使用以下

Process.WaitForExit();
this.Close();