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

本文关键字:线程 另一个 对话框 UI 显示 | 更新日期: 2023-09-27 18:06:44

我是c#新手,但我已经做了很多java。这是我的问题:我试图打开一个"SaveFileDialog"从一个线程,不是UI线程。

这正是我想做的:

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"不显示。

你有一些线索来帮助我从一个独立的线程显示对话吗?

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

让它看起来像这样:

    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>窗户比;线程窗口,看看UI线程正在做什么。除非UI线程处于空闲状态并正在执行Application.Run(),否则Control.Invoke()无法完成。如果不是,比如等待工作线程完成,那么这段代码总是会死锁。

从UI可用性的角度来看,这类代码也是有风险的。用户可能不希望这个对话框突然出现,并可能在UI线程拥有的窗口中鼠标或键盘时意外关闭它。

试试这个:

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;
    }
}