复杂的多线程接口

时间:2010-11-18 19:07:19

标签: winforms multithreading c#-4.0

首先,它不是我想要的闪屏...只是为了清楚......好吧......让我们来看看问题的描述:

我有一个激活N个线程的表单(我不知道用户必须选择多少个)...每个线程都有一个对象,并且在几个瞬间,对象可以触发一个事件来发出一些变化信号。每个线程必须有一个表单来“报告”事件正在发送的消息......

我的问题是:线程完美地创建了表单......但是消失了......不知道......它们出现在屏幕上......并且消失......噗......已经消失了!我怎样才能避免那种不受欢迎的“处置”?!?!

3 个答案:

答案 0 :(得分:2)

您的主题必须

  • 使用适当的InvokeRequired + Invoke logic
  • 或运行自己的MessagePump(Application.Run)

你(不)做了哪一个?

答案 1 :(得分:1)

必须在具有消息循环的线程上托管Form。您可以通过调用Application.RunForm.ShowDialog来创建消息循环。但是,除非你有充分的理由这样做,否则我会避免使用多个带有Windows消息循环的线程。

我也会避免创建N个线程。除了为每个操作创建一个线程之外,还有更好的方法来并行化N个操作。仅列举两个:1)在ThreadPool或2)中排队工作项通过Task类使用任务并行库。创建N个线程的问题是每个线程消耗一定量的资源。更多线程意味着将消耗更多资源并且将发生更多上下文切换。在多线程领域,更多并不总是更好。

答案 2 :(得分:1)

如果在线程中创建表单,则表单将在线程完成时消失。如果您希望表单存活的时间长于您需要保持线程处于活动状态,或者在应用程序的主线程上创建表单。后者更可取。只需确保每个都以相应的形式连接对象的事件侦听器,并在更新表单时根据需要使用InvokeBeginInvoke

一个简单的例子:

首先是一名工人:  班级工人     {         公共事件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
    }
}

然后,在一个表单中,我们有一个SomethingHappened事件的事件处理程序:

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

    // update gui here
}

然后,这只是将它们连接在一起的问题:

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

免责声明:这个样本很快被一起扔掉,有些未经测试(坐在火车上,即将下车;)。)。