我的项目是一个在后端与WCF服务对话的三层架构项目。当后端能够从服务获取数据时,它使用publish-subscribe通知业务层,业务层反过来通知GUI层。
我已经使用Visual Studios designer在我的UI设计中添加了一个OpenFileDialog。按钮事件处理程序调用ShowDialog消息。但是,一旦我单击该按钮,整个UI就会挂起。
在谷歌了一下之后,我发现使用委托是处理此类任务的首选方法。然而,在没有委托的情况下,问题仍然存在。
目前,我的代码如下所示:
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编程并不是很熟悉。
我有什么遗漏的吗?
发布于 2011-07-17 19:07:13
我似乎已经解决了将STAThread属性添加到main方法中的问题。当我在调试器中运行程序时,我被告知要这样做-这是我以前没有做过的,因为我从Visual Studio运行服务,从Windows定期运行客户端。
[STAThread]
public static void Main(string[] args)
{
GUI gui = new GUI();
gui.ShowDialog();
}有人能解释一下到底是怎么回事吗?
发布于 2016-08-10 23:52:20
openFileDialog1->ShowHelp = true;我把这一行放到我的代码中,然后问题就解决了。
发布于 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协定所必需的。当你不这样做的时候就会陷入僵局。
https://stackoverflow.com/questions/6718148
复制相似问题