开发者

Complex multi-threaded interface

First of all its not a splash-screen what i want... just to be clear... ok... lets go to the description of the problem:

i have a form that fire N number of threads (i dont know how many, the user must choose)... each thread has a object, and 开发者_如何学运维during several moments the objects may fire a event to signal some change... there must be a form for each thread to "report" the messages that the events are sending...

my problem is: the threads create the forms perfectally... but the desappear... out of nowhere... they appear on the screen... and vanish... poof.... gone! how can i avoid that undesired "disposing"?!?!


Your threads must either

  • use proper InvokeRequired + Invoke logic
  • or run their own MessagePump (Application.Run)

Which one did you (not) do?


If you create a form in a thread, the form will vanish when the thread is done. If you want the form to survive longer than that you need to either keep the thread alive, or create the form on the application's main thread. The latter would be preferable. Just make sure that each to hook up event listener for the object in the corresponding form, and use Invoke or BeginInvoke as needed when updating the form.

A simple example:

First a worker: class Worker { public event EventHandler SomethingHappened;

    protected void OnSomethingHappened(EventArgs e)
    {
        var evnt = SomethingHappened;
        if (evnt != null)
        {
            evnt(this, e);
        }
    }
    public void Work()
    {
        // do lots of work, occasionally calling
        // OnSomethingHappened
    }
}

Then, in a form we have an event handler for the SomethingHappened event:

public void SomethingHappenedHandler(object sender, EventArgs e)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new Action(() => SomethingHappenedHandler(sender, e)));
        return;
    }

    // update gui here
}

Then it's really just a matter of wiring it all together:

Worker w = new Worker();
ProgressForm f = new ProgressForm;
w.SomethingHappened += f.SomethingHappenedHandler; 
f.Show();   
Thread t = new Thread(w.Work);
t.Start();

Disclaimer: this sample is quickly tossed together and somewhat untested (sitting on the train, about to get off ;) ).


A Form must be hosted on a thread with a message loop. You can create a message loop by either calling Application.Run or Form.ShowDialog. However, unless you have really good reason for doing so I would avoid having more than one thread with a windows message loop.

I would also avoid creating N threads. There are better ways to parallelize N operations other than creating one thread per operation. To name only two: 1) queue a work item in the ThreadPool or 2) use the Task Parallel Library via the Task class. The problem with creating N threads is that each thread consumes a certain amount of resources. More threads means more resources will be consumed and more context switching will occur. More is not always better in the world of multithreading.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜