开发者

Starting multiple gui (WinForms) threads so they can work separetly from one main gui in C#?

开发者 https://www.devze.com 2022-12-21 11:10 出处:网络
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 pu

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.


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


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.


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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号