我是C#的新手,但我做了很多java。这是我的问题:我正在尝试从不是UI线程的线程中打开“SaveFileDialog”。
这正是我尝试做的事情:
public partial class Form1: Form
{
public string AskSaveFile()
{
var sfd = new SaveFileDialog();
sfd.Filter = "Fichiers txt (*.txt)|*.txt|Tous les fichiers (*.*)|*.*";
sfd.FilterIndex = 1;
sfd.RestoreDirectory = true;
DialogResult result = (DialogResult) Invoke(new Action(() => sfd.ShowDialog(this)));
if(result == DialogResult.OK)
{
return sfd.FileName;
}
return null;
}
}
将始终从与拥有表单的线程不同的线程调用此方法。问题是,当我执行此代码时,“Form1”冻结并且“SaveFileDialog”没有显示。
您是否有一些线索可以帮助我从独立的线程中显示对话框?
答案 0 :(得分:11)
让它看起来像这样:
public string AskSaveFile() {
if (this.InvokeRequired) {
return (string)Invoke(new Func<string>(() => AskSaveFile()));
}
else {
var sfd = new SaveFileDialog();
sfd.Filter = "Fichiers txt (*.txt)|*.txt|Tous les fichiers (*.*)|*.*";
sfd.FilterIndex = 1;
sfd.RestoreDirectory = true;
return sfd.ShowDialog() == DialogResult.OK ? sfd.FileName : null;
}
}
如果仍然遇到死锁,请务必使用调试器的Debug + Windows + Threads窗口,查看UI线程正在做什么。除非UI线程处于空闲状态并且泵送消息循环,否则Control.Invoke()无法完成。等待工作线程完成总是会导致死锁。
另外考虑到这种代码存在风险,用户可能不希望这个对话框在UI线程拥有的窗口中进行鼠标或键盘输入时突然显示并意外关闭它。
答案 1 :(得分:6)
试试这个:
public partial class Form1: Form
{
public string AskSaveFile()
{
if (this.InvokeRequired)
{
Invoke( new MethodInvoker( delegate() { AskSaveFile(); } ) );
}
else
{
var sfd = new SaveFileDialog();
sfd.Filter = "Fichiers txt (*.txt)|*.txt|Tous les fichiers (*.*)|*.*";
sfd.FilterIndex = 1;
sfd.RestoreDirectory = true;
if(sfd.ShowDialog() == DialogResult.OK) return sfd.FileName;
}
return null;
}
}