简体   繁体   中英

C# : Show dialog on UI thread from another thread

I'm new to C#, but i've done a lots of java. Here's my problem : I'm trying to open a "SaveFileDialog" from a thread that is not the UI thread.

This is exactly what I try to do:

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

This method will always be called from a thread different from the one who owns the Form. The problem is that when I execute this code, the "Form1" freeze and the "SaveFileDialog" doesn't show up.

Do you have some clue to help me to show the dialog from an independant thread?

Make it look like this:

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

If you still get deadlock then be sure to use the debugger's Debug + Windows + Threads window and look at what the UI thread is doing. Control.Invoke() cannot complete unless the UI thread is idle and pumping the message loop. Waiting for the worker thread to finish is always going to cause deadlock.

Also consider that this kind of code is risky, the user might not expect this dialog to suddenly show up and accidentally close it while mousing or keyboarding in the window(s) owned by the UI thread.

Try this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM