C# &引用;请稍等;表单隐藏主表单

C# &引用;请稍等;表单隐藏主表单,c#,winforms,multithreading,C#,Winforms,Multithreading,我的应用程序中有一些很长的进程,因此我创建了一个“请等待”表单,并调用了另一个线程,如下所示: public void ShowWait() { continueWait = true; ThreadPool.QueueUserWorkItem((x) => { using (frmWait espera = new frmWait()) {

我的应用程序中有一些很长的进程,因此我创建了一个“请等待”表单,并调用了另一个线程,如下所示:

public void ShowWait()
    {
        continueWait = true;
        ThreadPool.QueueUserWorkItem((x) =>
            {
                using (frmWait espera = new frmWait())
                {
                    espera.ShowInTaskbar = false;
                    espera.Show();
                    while (continueWait)
                        Application.DoEvents();
                    espera.Close();
                }
            });
    }
要关闭我使用的表单,请执行以下操作:

public void HideWait()
    {
        continueWait = false;
    }
它工作正常,但我有一个问题,当显示等待表单时,主表单会失去焦点,同时运行的任何其他应用程序(Excel、Word等)会转到顶部,而我的应用程序会转到所有应用程序的后面。我尝试使用Activate()和Focus(),但只有任务栏上的框架激活,但应用程序仍保留在所有应用程序的背面

有什么线索吗


提前谢谢

我希望我能正确理解你的问题。所以你想把WaitForm设置在最上面?如果是的话,你有没有设定

espera.TopMost = true;

属性?

我想你想要一个模态形式,试试看

espera.ShowDialog();

OTOH我真的不明白你想要什么,所以我可能错了。

你的代码片段没有为我重现问题。真正重要的是主窗体发生了什么。你看到发生的事情并不是那么不寻常。当您的等待窗体关闭时,Windows将在您的应用程序中寻找另一个窗口,以便将焦点提供给您的应用程序。如果找不到,它将从另一个进程中选择另一个窗口,并将其带到前台。实际上,您的主窗体将消失在该窗口后面

当主窗体被禁用时,肯定会发生这种情况,也许您将其Enabled属性设置为false?我想,当您的主窗体仍然对Windows消息没有响应时,也会发生这种情况,因为这一部分是模糊的


通过在后台线程而不是UI线程上执行耗时的代码来避免此类问题(以及用于等待表单的错误线程单元)。BackgroundWorker的设计就是为了让这变得简单。

我无法复制其他应用程序,但与Fredrik建议放弃while循环相关,这对我来说是可行的:

AutoResetEvent processing = new AutoResetEvent(false);

private void HideWait()
{
    processing.Set();
}

private void ShowWait()
{           
    ThreadPool.QueueUserWorkItem((x) =>
    {
        using (frmWait espera = new frmWait())
        {
            espera.ShowInTaskbar = false;
            espera.Show();
            processing.WaitOne();
            espera.Close();
        }
    });
}
编辑:

为避免主窗体失去焦点,请执行以下操作:

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

static readonly int SW_SHOWNOACTIVATE = 4;

AutoResetEvent processing = new AutoResetEvent(false);

private void HideWait()
{
    processing.Set();
}

private void ShowWait()
{
    ThreadPool.QueueUserWorkItem(c =>
    {
        using (frmWait espera = new frmWait())
        {
            espera.ShowInTaskbar = false;
            ShowWindow(espera.Handle, SW_SHOWNOACTIVATE);
            processing.WaitOne();
            }
        });
    }
}

您是否尝试过使用
Show
重载来接受所有者窗口,并向其传递空引用?我过去也遇到过类似的问题,这些问题都是通过这种方式解决的:

espera.Show(null);

调用
Show()
(它在类型
控件中实现,并简单地设置
Visible=true
,在本例中,这反过来触发类型
表单中的代码)和调用
Show(owner)
的行为似乎有些不同

是的,我已经设置了属性,等待表单显示正确,问题在于主表单。我强烈建议您使用您在
HideWait
方法中发出信号的waithandle(例如
ManualResetEvent
)替换while循环。这样,您就不会使用任何不必要的CPU资源。当我使用手动或自动重置事件时,应用程序将挂起,等待窗体不会显示等待动画,整个应用程序将等待信号。已多次解决此问题。。。看一看:1。2.等待表单的TopMost=true,因此ShowDialog()不是必需的。ShowDialog可能是您想要的,因为当任务完成时,当等待表单关闭时,主表单将获得焦点。(我想)我试着使用ShowDialog,但是等待表单出现在右上角,主表单仍然没有焦点。嗨,亲爱的,我需要一个简单的项目。你能帮我发送或给我一个链接吗。提前谢谢。阿巴斯。zolfaghari@gmail.com