C#:从另一个线程显示UI线程上的对话框
我是C#新手,但我做过很多java。我的问题是:我试图从一个不是UI线程的线程打开一个“SaveFileDialog” 这正是我想做的:C#:从另一个线程显示UI线程上的对话框,c#,winforms,multithreading,dialog,C#,Winforms,Multithreading,Dialog,我是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 (
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”不会显示
您有什么线索可以帮助我从独立线程显示对话框吗?试试这个:
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;
}
}
让它看起来像这样:
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;
}
}
公共字符串AskSaveFile(){
if(this.invokererequired){
返回(字符串)调用(newfunc(()=>AskSaveFile());
}
否则{
var sfd=new SaveFileDialog();
sfd.Filter=“Fichiers txt(*.txt)|*.txt | Tous les Fichiers(*.*)|*.”;
sfd.FilterIndex=1;
sfd.RestoreDirectory=true;
返回sfd.ShowDialog()==DialogResult.OK?sfd.FileName:null;
}
}
如果仍然出现死锁,请确保使用调试器的Debug+Windows+Threads窗口,并查看UI线程正在执行的操作。除非UI线程处于空闲状态并泵送消息循环,否则无法完成Control.Invoke()。等待工作线程完成总是会导致死锁
也认为这种代码是有风险的,用户可能不希望这个对话框在UI线程所拥有的窗口中弹出或键入时突然出现并意外关闭它。
不工作:“ASKSaveFILE”需要返回字符串。如果我用“EndInvoke”等待结果,我也会遇到同样的问题(“Form1”冻结)。。。所以这可以奏效。。。。哦,是的,主线程将执行此。。但是你的意思是你的主线程正在做一些不同的事情,不能使用吗?相信我,在我的应用程序中,我在不同的线程中使用了这些代码,它可以工作。。。汉斯:你的评论是对我的还是对马修的?你是对的,第一部分是有效的,它显示了对话。但我找到了解决办法。我已经将调用该方法的线程设置为“STA”,现在是这个线程为您执行方法“sfd.ShowDialog()”。C#编译器不允许您编写不保证返回值始终设置的代码。谢谢,这对我来说很有效。我在FolderBrowserDialog中使用了它