Windows Forms GUI freezes when OpenFileDialog.ShowDialog () is called

my project is a three-tier architecture project talking to the WCF service in the backend. When a backend can retrieve data from a service, it notifies the business layer using a subscription publication, which in turn notifies the GUI layer.

I added OpenFileDialog to my UI design using the Visual Studios designer. The button event handler invokes the ShowDialog message. However, as soon as I click the button, the whole user interface freezes.

Having died a little, I found that using delegates is the preferred way to solve such problems. However, with and without a delegate, the problem persists.

Currently my code is as follows:

private void bOpen_Click(object sender, EventArgs e) { Func<Image> del = delegate { OpenFileDialog d = new OpenFileDialog(); if (d.ShowDialog() == DialogResult.OK) { return Image.FromFile(d.FileName); } return null; }; Invoke(del); } 

I come from the Java world, so I'm not very good at the intricacies of C # UI programming.

Anything I miss here?

+4
source share
4 answers

I seem to have solved the problem by adding the [STAThread] attribute to the main method. I was told to do this as soon as I ran the program in the debugger, which I did not do before, because I regularly started the service from Visual Studio and the client from Windows.

 [STAThread] public static void Main(string[] args) { GUI gui = new GUI(); gui.ShowDialog(); } 

Can someone explain what exactly is happening though

+9
source

This is usually an environmental issue, when you use OpenFileDialog, many shell extensions are loaded into your process. Incorrect behavior can easily ruin your program. There are a lot of bad ones.

Debugging is difficult, you need an unmanaged debugger, because these shell extensions are unmanaged code. You might be able to say something from the call stack when you enter a dead end after a dead end. Windows Debugging Symbols Required, Enable Microsoft Symbol Server. But the most efficient approach is to use the SysInternals utility for AutoRuns. Start by disabling all shell extensions that were not created by Microsoft. Then, re-enable those that you cannot live without one at a time.

And, as you know, this shell extension is expected to run on the STA stream and fails when they do not receive it. The user interface of the program should always be STA, also to support the clipboard and drag and drop and various types of controls, such as WebBrowser. Usually it is always automatically processed by the [STAThread] attribute in the Main () method placed there by the project template. And the Application.Run () call needed to implement the STA contract. Dead end if you don’t.

+7
source

I believe the preferred delegate method refers to using a separate thread. I will give you an example with BackgroundWorker.

It will look like this:

 public partial class Form1 : Form { public Form1() { InitializeComponent(); m_Worker.DoWork += new DoWorkEventHandler(m_Worker_DoWork); m_Worker.ProgressChanged += new ProgressChangedEventHandler(m_Worker_ProgressChanged); m_Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_Worker_RunWorkerCompleted); } void m_Worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { //Usually, used to update a progress bar } void m_Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //Usually, used to add some code to notify the user that the job is done. } void m_Worker_DoWork(object sender, DoWorkEventArgs e) { //e.Argument.ToString() contains the path to the file //Do what you want with the file returned. } private void bOpen_Click(object sender, EventArgs e) { OpenFileDialog d = new OpenFileDialog(); if (d.ShowDialog() == DialogResult.OK) { m_Worker.RunWorkerAsync(d.FileName); } } BackgroundWorker m_Worker = new BackgroundWorker(); } 

Now, because of your user interface, it freezes, this is because by default your work is done in the user interface thread, so if you run something heavy, the user interface will not respond.

+4
source
 openFileDialog1->ShowHelp = true; 

I put this line in my code, then the problem was solved.

+4
source

All Articles