C#:在另一个线程的UI线程上显示对话框

Moi*_*ime 9 c# multithreading dialog winforms

我是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;
    }
}
Run Code Online (Sandbox Code Playgroud)

始终从与拥有表单的线程不同的线程调用此方法.问题是,当我执行此代码时,"Form1"冻结并且"SaveFileDialog"不会显示.

你有什么线索可以帮助我从一个独立的线程中显示对话框吗?

Han*_*ant 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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果你仍然遇到死锁,那么一定要使用调试器的Debug + Windows + Threads窗口,看看UI线程在做什么.除非UI线程处于空闲状态并且泵送消息循环,否则Control.Invoke()无法完成.等待工作线程完成总是会导致死锁.

还要考虑到这种代码存在风险,用户可能不会期望在UI线程拥有的窗口中进行鼠标或键盘输入时突然显示该对话框并意外关闭它.


Mar*_*rco 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;
    }
}
Run Code Online (Sandbox Code Playgroud)