Winforms 复杂多线程接口
首先,这不是一个启动屏幕我想要的。。。我只是想说清楚。。。好啊让我们转到问题的描述: 我有一个表单可以触发N个线程(我不知道有多少,用户必须选择)。。。每个线程都有一个对象,在若干时刻,这些对象可能会触发一个事件来表示某些更改。。。每个线程必须有一个表单来“报告”事件发送的消息Winforms 复杂多线程接口,winforms,multithreading,c#-4.0,Winforms,Multithreading,C# 4.0,首先,这不是一个启动屏幕我想要的。。。我只是想说清楚。。。好啊让我们转到问题的描述: 我有一个表单可以触发N个线程(我不知道有多少,用户必须选择)。。。每个线程都有一个对象,在若干时刻,这些对象可能会触发一个事件来表示某些更改。。。每个线程必须有一个表单来“报告”事件发送的消息 我的问题是:线程完美地创建表单。。。但是脱衣舞。。。不知从哪里冒出来。。。它们出现在屏幕上。。。然后消失。。。噗。。。。跑了!我怎样才能避免不必要的“处置” 您的线程必须 使用适当的invokererequired+调
我的问题是:线程完美地创建表单。。。但是脱衣舞。。。不知从哪里冒出来。。。它们出现在屏幕上。。。然后消失。。。噗。。。。跑了!我怎样才能避免不必要的“处置” 您的线程必须
- 使用适当的invokererequired+调用逻辑
- 或者运行自己的消息泵(Application.run)
你(没有)做了哪一个?一个
表单
必须托管在一个带有消息循环的线程上。您可以通过调用Application.Run
或Form.ShowDialog
来创建消息循环。然而,除非你有很好的理由这样做,否则我会避免有一个以上的windows消息循环线程
我也会避免创建N个线程。除了为每个操作创建一个线程外,还有更好的方法来并行N个操作。仅举两个例子:1)在
ThreadPool
中对工作项进行排队,或2)通过Task
类使用任务并行库。创建N个线程的问题是,每个线程都会消耗一定数量的资源。更多的线程意味着将消耗更多的资源,并且将发生更多的上下文切换。在多线程世界中,更多并不总是更好的。如果在线程中创建表单,那么当线程完成时,表单将消失。如果您想让表单存活更长的时间,您需要保持线程的活动状态,或者在应用程序的主线程上创建表单。后者更可取。只需确保每个应用程序都可以在相应的表单中连接对象的事件侦听器,并在更新表单时根据需要使用or
一个简单的例子:
首先是工人:
班主任
{
公共事件处理程序发生了什么事情
protected void OnSomethingHappened(EventArgs e)
{
var evnt = SomethingHappened;
if (evnt != null)
{
evnt(this, e);
}
}
public void Work()
{
// do lots of work, occasionally calling
// OnSomethingHappened
}
}
然后,在表单中,我们为SomeThingOccessed事件提供了一个事件处理程序:
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();
免责声明:此示例很快就被抛到了一起,有些未经测试(坐在火车上,即将下车;))。我正在使用.Net 3.5,没有任何任务…sob…而且用户必须定义同时有多少线程在工作…@Leonardo:Microsoft有一个任务并行库的后端口,其中包括
任务
类,可通过反应式扩展下载用于.Net 3.5。只需谷歌即可。@Leonardo:让用户指定线程数更糟糕。最终用户不可能比开发人员更好地判断最佳线程数。是的……我知道……我能做什么?!那家伙说他想那样做,但不会采取任何其他方式……而且……我需要吃2个……我怎么做?从thread调用主窗体并创建一个新窗体?我不太喜欢这样做,但我使用了这个想法。Tks!