views:

221

answers:

4

I've one MainForm window and from that user can press 3 buttons. Each of the button starts new Form in which user can do anything he likes (like time consuming database calls etc). So i decided to put each of the forms in it's own threads:

   private Thread subThreadForRaportyKlienta;
   private Thread subThreadForGeneratorPrzelewow;
   private Thread subThreadForRaporty;
   private void pokazOplatyGlobalne() {
           ZarzadzajOplatamiGlobalneDzp varGui = new ZarzadzajOplatamiGlobalneDzp();
           varGui.ShowDialog();
    }
    private void pokazRaportyKlienta() {
          RaportyDzpKlient varGui = new RaportyDzpKlient();
           varGui.ShowDialog();
    }       
    private void pokazRaportyWewnetrzne() {
       RaportyDzp varGui = new RaportyDzp();
        varGui.ShowDialog();
    }
    private void pokazGeneratorPrzelewow() {
        ZarzadzajPrzelewamiDzp varGui = new ZarzadzajPrzelewamiDzp();
        varGui.ShowDialog();
    }
    private void toolStripMenuGeneratorPrzelewow_Click(object sender, EventArgs e) {
        if (subThreadForGeneratorPrzelewow == null || subThreadForGeneratorPrzelewow.IsAlive == false) {
            subThreadForGeneratorPrzelewow = new Thread(pokazGeneratorPrzelewow);
            subThreadForGeneratorPrzelewow.Start();
        } else {

        }

    }
    private void toolStripMenuGeneratorRaportow_Click(object sender, EventArgs e) {
        if (subThreadForRaporty == null || subThreadForRaporty.IsAlive == false) {
            subThreadForRaporty = new Thread(pokazRaportyWewnetrzne);
            subThreadForRaporty.Start();
        } else {

        }
    }
    private void toolStripMenuGeneratorRaportowDlaKlienta_Click(object sender, EventArgs e)
    {
        if (subThreadForRaportyKlienta == null || subThreadForRaportyKlienta.IsAlive == false) {
            subThreadForRaportyKlienta = new Thread(pokazRaportyKlienta);
            subThreadForRaportyKlienta.Start();
        } else {

        }
    }

I've got couple of questions and i hope someone could explain them:

  1. When i use Show() instead of ShowDialog() the windows just blink for a second and never shows. What's the actual difference between those two and why it happens?
  2. When i use ShowDialog everything seems normal but i noticed not everything gets filled properly in one of the gui's (one listView stays blank even thou there are 3 simple add items in Form_Load(). I noticed this only in one GUI even thou on first sight everything works fine in two other gui's and i can execute multiple tasks inside those Forms updating those forms in background too (from inside the forms methods). Why would this one be diffrent?
  3. What would be proper way of doing this? Tasks performed in each of those Forms can be time consuming and i would like to give user possibility to jump between those 4 windows without problem so he can execute what he likes.
+1  A: 

You should put the time-consuming tasks in their own BackgroundWorker threads. Keep all of the forms in the main thread.

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Jake
Doing that i loose ability to switch between forms in easy form (like ALT+TAB). And lets say i have 2 or 3 monitors i would like to be able to put all those 3 forms on 3 different monitors and be responsive and doing their own things.
MadBoy
You would definitely not have issues with responsiveness. If you place each time-consuming task in its own worker thread, there is nothing to hold up the main UI thread. You can place your forms wherever you'd like and interact with all of them simultaneously so long as you keep the actual *work* in the worker threads and you call the forms with "Show" as Asad mentioned. If you want each form to be treated as a separate application, you should write them as separate applications that you can launch as separate processes from a switchboard.
Jake
Jake this is what i didn't knew about. Behaviour of Show prevents me from doing threads to start the gui. I thought they always have to be started in blocking way so to fix that i would have to start new thread. But since as Asad pointed Show is non blocking i can use main thread for GUI and have other threads for background work (which i already do).
MadBoy
@Sameh: nothing. I didn't knew Show was nonblocking, so i thought i will have to start new thread to have non blocking forms. What i was doing i was shooting thread to start each gui and in that gui i was shooting another thread to do the work. So gui was responsive, i was able to jump between gui's too just some things were missing, not working correctly.
MadBoy
+3  A: 

The difference is with Modal and Modeless Windows Forms.

Modeless forms let you shift the focus between the form and another form without having to close the initial form

Show() method is used for this purpose

Asad Butt
Just read this article. Seems my putting forms in threads was pointless! I feel like a noob every single day :/
MadBoy
you should not. checking more options, evaluating, rejecting some and choosing one is better thing to do than sitting aside fearing that your thoughts might lead you this useless `noob ` like feelings.
Asad Butt
How would i know when Window is closed? Since Show is non blocking method gets back to what it was doing.
MadBoy
A: 

1: Show() is not blocking, that is it shows the window and then returns. Afterwards, the varGui variable goes out of scope and is finalized by the garbage collector => disappears.

2: You'd need to show the updating code to get a definite answer, but as you can only update the contents of a form when running in the thread that created the form. Doing it otherwise is unreliable, so is the usual culprit when form updates don't work. In a method of a form class, call:

if (InvokeRequired) { 
   .Invoke(..); // call back this same method on the right thread
} else {
 // dowork 
}

to manage the UI.

3: The proper way is what Jake wrote: use one thread for all GUI stuff and BackgroundWorker threads for, well, background work.

Timores
+1  A: 

Show() shows the new form, then returns. If this is all the thread is doing than the thread will exit, and that will destroy the form.

ShowDialog() shows the form, and then begins running a message pump, until the form is hidden or destroyed, ShowDialog() doesn't return, so your thread keeps running.

If You mean for these forms to each behave like a separate application window. then you could also use Application.Run() after form.Show() to run a message pump for the form on that thread. The drawback to doing it this way, is that when any one of your forms is closed, it might end up taking down the whole process because of the way WM_QUIT is handled.

But other than the way you would deal with closing down your application, Form.ShowDialog() is very much like Form.Show() followed by Application.Run(). The conditions that cause the message pump to exit are a bit different between these to, so you would choose one or the other mostly based on how you want to your application to handle closing one of your forms.

John Knoeller
Thanks for brief explanation. Form.Show() is what i need to use.
MadBoy