gpt4 book ai didi

c# - 从另一个线程调用 show 后 Windows 窗体窗体挂起

转载 作者:行者123 更新时间:2023-11-30 14:16:22 29 4
gpt4 key购买 nike

我的应用程序有一些异步运行的网络代码。我已经附加了一些在没有连接到服务器时要抛出的事件,并且在发生这种情况时我正在创建一些“操作失败”表单。问题是我的表单在创建后挂起。我阅读了相关内容并尝试使用:

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);
}
}
}

你能告诉我在这个具体问题上要改变什么吗?

最佳答案

作为第一步,使用以下方法从 ShowForm2() 中删除递归:

Action a = new Action(() => form.Show());

现在详细解释发生了什么:当这些行在 button1_Click() 中被注释时

    //form.Show();
//form.Hide();

然后在 ShowForm2() 中,form.InvokeRequired 将为假。这意味着该表单与您的工作在同一线程中执行,这就是表单“挂起”的原因。

但是当您取消注释这些行时,相同的 form.InvokeRequired 将为真,这意味着该表单正在 UI 线程中执行,这就是 form2 响应的原因。

解决方案是强制 form2 在 UI 线程中运行,但您不希望像示例中那样出现闪烁,因此您必须尝试使用​​其他方法。

解决方案是在创建表单后使用 form.Handle 属性。 Form.Handle 在第一次使用时创建。在你的情况下是在 form.Show() 上。显然,在所需的线程中创建句柄很重要,而不仅仅是表单包装器。我将附上修改后的代码以使事情更清楚。

我不确定解释是否正确,但是 handle = form.Handle; 会解决您的问题。

public partial class Form1 : Form
{
Form form;
IntPtr handle;

public Form1()
{
InitializeComponent();
form = new Form();
handle = form.Handle;
}

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

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

关于c# - 从另一个线程调用 show 后 Windows 窗体窗体挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7727881/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com