首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调用OpenFileDialog.ShowDialog()时Windows窗体图形用户界面挂起

调用OpenFileDialog.ShowDialog()时Windows窗体图形用户界面挂起
EN

Stack Overflow用户
提问于 2011-07-16 22:54:51
回答 6查看 16.3K关注 0票数 7

我的项目是一个在后端与WCF服务对话的三层架构项目。当后端能够从服务获取数据时,它使用publish-subscribe通知业务层,业务层反过来通知GUI层。

我已经使用Visual Studios designer在我的UI设计中添加了一个OpenFileDialog。按钮事件处理程序调用ShowDialog消息。但是,一旦我单击该按钮,整个UI就会挂起。

在谷歌了一下之后,我发现使用委托是处理此类任务的首选方法。然而,在没有委托的情况下,问题仍然存在。

目前,我的代码如下所示:

代码语言:javascript
复制
private void bOpen_Click(object sender, EventArgs e)
{
    Func<Image> del = delegate
    {
        OpenFileDialog d = new OpenFileDialog();
        if (d.ShowDialog() == DialogResult.OK)
        {
            return Image.FromFile(d.FileName);
        }

        return null;
    };

    Invoke(del);
}

我来自Java界,所以对错综复杂的C# UI编程并不是很熟悉。

我有什么遗漏的吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-07-17 19:07:13

我似乎已经解决了将STAThread属性添加到main方法中的问题。当我在调试器中运行程序时,我被告知要这样做-这是我以前没有做过的,因为我从Visual Studio运行服务,从Windows定期运行客户端。

代码语言:javascript
复制
[STAThread]
public static void Main(string[] args)
{
    GUI gui = new GUI();
    gui.ShowDialog();
}

有人能解释一下到底是怎么回事吗?

票数 9
EN

Stack Overflow用户

发布于 2016-08-10 23:52:20

代码语言:javascript
复制
openFileDialog1->ShowHelp = true;

我把这一行放到我的代码中,然后问题就解决了。

票数 12
EN

Stack Overflow用户

发布于 2011-07-16 23:26:45

这往往是一个环境问题,当您使用OpenFileDialog时,很多shell扩展都会加载到您的进程中。一个行为不端的人很容易把你的程序搞砸。外面有很多不好的。

调试这很困难,您需要一个非托管调试器,因为这些shell扩展都是非托管代码。当您在死锁之后进入时,您也许能够从调用堆栈中辨别出一些东西。需要Windows调试符号,请启用Microsoft符号服务器。但最有效的方法是使用SysInternals的AutoRuns实用程序。首先,禁用所有非Microsoft生产的shell扩展。然后开始逐个重新启用那些你离不开的东西。

而且,正如您所发现的,这些shell扩展期望在STA线程上运行,并且当它们得不到它时会失败得很糟糕。程序的UI线程必须始终是STA,也要支持剪贴板、拖放和各种控件,如WebBrowser。通常总是由Main()方法上的STAThread属性自动处理,由项目模板放在那里。以及Application.Run()调用,这是实现STA协定所必需的。当你不这样做的时候就会陷入僵局。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6718148

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档