【问题标题】:how to show a form while process is going on current form如何在处理当前表单时显示表单
【发布时间】:2012-01-20 06:37:21
【问题描述】:

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

我有 2 个表单,在 form2 上,在单击按钮时我执行了一个漫长的过程, 我希望我的“frmWait”出现在屏幕上,而 form2 上的过程正在进行,完成后消失。当我的“frmWait”出现时,用户应该无法访问表单 2。

我的代码在这里。 表格2

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

    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++)
                { }
            }
        }
    }

【问题讨论】:

  • 谢谢大家回复。但这里需要更多规范,在流程 SomeWork 和表单 Form2 上我无权访问,我可以访问 frmwait,此表单将是一种通用表单,任何人都需要等待,而长流程将在 15 人的团队中调用 frmwait程序员。
  • 我想为此准备一个简单的解决方案,正在使用frmwait的程序员,他必须在工作前显示frmWait并在工作后关闭它。一些工作进程应该在主线程中,直到一些工作没有完成用户不能在应用程序中执行进一步的任务。
  • 首先,您应该编辑您的问题,而不是添加评论。第二:不清楚。你的意思是你不能修改button1_Click中的代码?那你想怎么解决这个问题呢?
  • 你想做的是糟糕的设计/架构。 3 人推荐了 BackgroundWorker。你不觉得值得研究吗?
  • 对不起!对于不好的做法,我是新手,是的,我无法访问 button1_Click,当用户可以使用后台工作程序 form2 时,我希望 form2 应该停止直到进程完成,并且 frmwait 应该在进程进行时运行。

标签: c# winforms concurrency wait async-await


【解决方案1】:

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

一旦worker启动,使用frmWait.ShowDialog()显示frmWait。

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

您可以利用ProgressChanged 事件在您的frmWait 中报告进度。

如果用户在 frmWait 中单击取消按钮,只需在后台工作人员上调用 CancelAsync()

Full sample here.

【讨论】:

  • 当我使用后台工作人员表单 2 时,可以为用户提供更多操作
  • 没有,因为 frmWait 是模态的:frmWait.ShowDialog()
  • 在 frmWait.ShowDialog() 上执行停止不起作用,直到 frmwait 关闭才恢复。
  • 这就是你想要的:坐在那里等待后台线程完成 SomeProcess
【解决方案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();
} 

【讨论】:

  • 什么是“fw”,请您简要描述一下,我来自不同的文化,所以我在理解语言方面有些问题!
  • 而不是 fw.Show();试试 fw.Show(this);
  • 这将停止执行,直到 fw 未关闭才会恢复
  • 您的问题是您试图在一个线程中完成所有操作。你不应该在 UI 线程中做任何工作。这将导致您的 UI 挂起。我会尝试用完整的代码更新我上面的答案!
  • 哦,启动线程并然后显示对话框。当然!谢谢。这确实帮助我完成了启动加载;我在显示主窗体之前打开对话框的所有尝试导致应用程序在关闭等待对话框后失去焦点,但如果我在窗体已经显示时使用它,它可以工作。
【解决方案3】:

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

【讨论】:

  • 这很有趣且值得注意。不过OP的环境是VS2008/.NET3.5
【解决方案4】:

您应该在这种情况下使用 BackgroundWorkerSomeWork 部分从主 UI 线程移开

SomeWork(); 部分移动到BackgroundWorker 的单独DoWork 方法中。这样SomeWork 将由BackgroundWorker 在单独的后台线程中执行。然后在Background Work Completed 事件中,一旦SomeWork 完成,就会引发fw.Close();

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

    • 这将要求您长时间运行的进程是一个单独的可执行文件,您的对话框将在命令提示符下启动。我不认为这是你要找的。​​span>
    【解决方案6】:

    您可以使用模态拨号框。因为它不允许与其他表单交互(即 form2)

    frmWait.ShowDialog();
    

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

    【讨论】:

    • 当我使用 showdialog 执行中断直到 frmwait 没有关闭。但我想在处理过程中显示表单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2013-03-20
    • 1970-01-01
    相关资源
    最近更新 更多