如果软件组件内部尽可能避免线程?

时间:2011-01-23 15:18:02

标签: c# multithreading design-patterns f# components

我最近一直在研究代码,特别是在内部使用线程的面向组件的代码。这是一个不好的做法。我看到的代码来自一个F#示例,它展示了使用基于事件的编程技术。我不能在版权侵权的情况下发布代码,但它确实启动了自己的线程。这被认为是不好的做法,或者自己编写的代码是否可以完全控制线程创建是否可行。我确实指出这段代码不是一个可视化的组件,并且非常“从头开始构建”。

在线程有用的情况下,组件创建的最佳实践是什么?

我完全与语言无关,f#示例可能是在c#或python中。

我担心缺乏对组件运行时间和资源占用的控制,这个例子刚刚实现了另一个线程,但据我所知,没有什么能阻止这种类型的设计产生尽可能多的线程希望,以及你的计划允许的极限。

我确实考虑过诸如对象注入之类的方法,所以第四,但是线程很奇怪,因为它们是从组件角度来看纯粹的“动作”而不是“模型,状态,声明”

任何帮助都会很棒。

3 个答案:

答案 0 :(得分:8)

这是一个过于笼统的问题,无法承担任何比“依赖”更具体的答案: - )

有些情况下,在组件中使用内部线程是完全有效的,有时则没有。这必须根据具体情况决定。但总的来说,由于线程确实使代码更难以测试和维护,并且增加了细微的,难以发现的错误的机会,所以只有在确实有使用它们的决定性原因时才应谨慎使用它们。 / p>

合法使用线程的一个例子是工作线程,其中处理事件的组件启动一个需要很长时间才能执行的操作(例如冗长的计算,Web请求,或者扩展文件I / O),并产生一个单独的线程来完成这项工作,这样控件就可以立即返回到接口来处理进一步的用户输入。如果没有工作线程,UI会长时间完全没有响应,这通常会让用户生气。

另一个例子是冗长的计算/过程,它很适合并行执行,即它由许多或多或少相似大小的较小的独立任务组成。如果存在强大的性能要求,则使用工作线程池以并发方式执行各个任务确实有意义。许多语言为此类设计提供高级支持。

请注意,组件通常也可以自由分配和使用任何其他类型的资源,从而在无数其他方面造成严重破坏 - 您是否曾担心组件占用所有内存,耗尽可用文件句柄,保留端口等?其中许多可能会导致系统内全局问题,而不是产生额外的线程。

答案 1 :(得分:2)

在组件/库中创建新线程没有任何问题。唯一不对的是,如果它没有给API /组件的消费者提供一种在必要时进行同步的方法。

答案 2 :(得分:0)

首先,您所谈论的组件的性质是什么?它是一个被不同代码消耗的DLL吗?它有什么作用?有什么业务要求?所有这些对于确定您是否确实需要担心并行性至关重要。

其次,线程化只是一种能够实现更好的性能,响应性的工具,所以在任何地方都不惜一切代价避免使用线程并不是一种明智的方法 - 线程对于某些业务需求来说无疑是至关重要的。

第三,在比较c#和f#中的线程化语法时,你必须记住那些是他们自己的非常不同的野兽 - f#隐含地使线程更安全,因为没有全局变量的概念因此你的关键部分代码在f#中比在c#中更容易避免。这使得你作为一个去掉一个更好的地方,你不必处理内存块,锁,信号等。

我想说如果你的'组件'在很大程度上依赖于线程,你可能要考虑在c#中使用并行FX,或者甚至用f#,因为它采用更优雅的方式处理处理器时间切片和并行性(恕我直言) )。

最后但并非最不重要的是,当你说通过在组件中使用线程来提高计算机资源时 - 请记住,编码线程本身不一定会产生更高的资源影响 - 你可以轻易地对一个线程造成相同的损害线程,如果你没有正确处理你的对象(unmaneged),授予你在几个线程上犯同样的错误时可能会更快地得到OutOfMemeory Exception ...