Windows窗体形式挂从另一个线程调用演出后 [英] Windows Forms Form hanging after calling show from another thread

查看:170
本文介绍了Windows窗体形式挂从另一个线程调用演出后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序有一些网络代码异步运行。我附加了一些事件,当没有连接到服务器时抛出,我正在创建一些操作失败的形式,当发生这种情况。问题是我的形式在创建后挂起。我读了这个,我试图做:

  public void ShowView()
{
if (this.InvokeRequired)
{
Action a = new Action(ShowView);
this.Invoke(a);
}
else this.Show();
}

问题仍然存在。比我发现,如果控制没有创建InvokeRequired返回false。
所以我在我的初始化代码添加:

  this.show 
this.hide();

这种方式似乎工作。但它是相当丑陋,当我的应用程序启动,我可以看到一会儿我的形式被显示,而不是消失。
如何使我的表单创建所有的控件而不显示它,或者有更好的解决方案这个问题?



编辑: 更多信息。我使用MVP设计模式。我有Presenter对IView有依赖。我的窗体实现IView。 IView有这个ShowView()和HideVIew()方法,我从我的演示者调用。我的演示者从另一个线程接收事件。所以我应该在哪里做这个线程跳跃或我应该如何解决这个?



EDIT2:这里的示例应用程序说明问题:

  public partial class Form1:Form 
{
Form2 form;

public Form1()
{
InitializeComponent();
form = new Form2();
}

private void button1_Click(object sender,EventArgs e)
{
//form.Show();
//form.Hide();
Thread t = new Thread(new ThreadStart(ShowForm2));
t.Start();
}

private void ShowForm2()
{
if(form.InvokeRequired)
{
Action a = new Action(ShowForm2) ;
form.Invoke(a);
}
else
{
form.Show();
Thread.Sleep(5000);
}
}
}

你能告诉我 c>

code> InvokeRequired 有点离谱; InvokeRequired 将返回 true 随时从线程而非线程访问控件



所以如果你试图调用 Show() Hide()从另一个线程,你确实需要调用。 b
$ b

除了这个简短的解释,你没有提供足够的信息真正提供任何其他的想法。



EDIT

$ b可以发布一些相关的代码,例如在表单加载或激活时执行的任何代码。
$ b

您需要在创建和显示新表单之前返回到您的UI线程。正如在评论中指出的,显示它作为你的应用程序启动,然后隐藏它的工作,因为这是所有发生在UI线程。



一种方法,你可以做这是,如果你有一个MainForm总是可见的,你可以将你的 ShowView 方法到该表单,并使用 InvokeRequired <



另一个选择是设置 WindowState 最小化,以便最初显示时(在应用程序启动时),它不会显示在屏幕上(您也可以设置 ShowInTaskbar 更改为false)。然后,您的 ShowView 方法也可以更改 WindowState


I have application which has some networking code which runs asynchronously. I have attached some events to be thrown when no connection to server and I'm creating some "operation failed" form when this happens. The problem is that my form hangs after creation. I read about that and I tried to do with:

public void ShowView()
{
    if (this.InvokeRequired)
    {
        Action a = new Action(ShowView);
        this.Invoke(a);
    }
    else this.Show();
}

And problem was still present. Than I found that if control was not been created that InvokeRequired returns false. So I at my initialization code added:

this.show();
this.hide();

This way it seems to be working. But it is pretty ugly and when my app starts I can see for a moment my form being shown and than disappears. How should I make my form to create all of it controls without showing it, or is there some better solution to this problem?

EDIT: More information. I'm using MVP design pattern. I have Presenter which have dependency to IView. My form implements IView. IView has this ShowView() and HideVIew() methods which I call from my presenter. My presenter receives event from another thread. So Where should I do this thread jumping or how should I solve this?

EDIT2: Here sample app illustrating problem:

public partial class Form1 : Form
    {
        Form2 form;

        public Form1()
        {
            InitializeComponent();
            form = new Form2();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //form.Show();
            //form.Hide();
            Thread t = new Thread(new ThreadStart(ShowForm2));
            t.Start();
        }

        private void ShowForm2()
        {
            if (form.InvokeRequired)
            {
                Action a = new Action(ShowForm2);
                form.Invoke(a);
            }
            else
            {
                form.Show();
                Thread.Sleep(5000);
            }
        }
    }

Can you tell me on this concrete problem what to change?

解决方案

Your understanding of Invoke and InvokeRequired is a little off; InvokeRequired will return true anytime a control is being accessed from a thread other than the thread it was created on (usually called the "UI Thread").

So if you're attempting to call Show() or Hide() from another thread, you do indeed need to Invoke it.

Other than that brief explanation, you haven't provided enough information to really offer any other ideas. Maybe you can post some relevant code, like any code that executes when the form is loaded or activated.

EDIT

You need to get back to your UI thread before you create and show the new form. As has been pointed out in comments, showing it as your application starts up and then hiding it works because that is all happening on the UI thread.

One way you can do this is, if you have a "MainForm" that is always visible, you can move your ShowView method to that form, and use the InvokeRequired`Invoke` pattern to keep the work on the UI Thread.

Another option is to set the WindowState to Minimized by default, so that when it is initially shown (at application start) it's not visible on the screen (you could also set the ShowInTaskbar to false). Then your ShowView method could also change the WindowState.

这篇关于Windows窗体形式挂从另一个线程调用演出后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆