如果可能的话,是否应该在软件组件内部避免线程?
我最近一直在研究代码,特别是内部使用线程的面向组件的代码。这是一个不好的做法吗?我查看的代码来自 F# 示例,该示例展示了基于事件的编程技术的使用。如果侵犯版权,我无法发布代码,但它确实会启动自己的线程。这是否被视为不好的做法,或者不是由您自己编写的代码可以完全控制线程创建是否可行。我确实指出,这段代码不是可视组件,而是“从头开始构建”的。
线程有帮助的组件创建最佳实践有哪些?
我对此完全与语言无关,f# 示例可能是 c# 或 python 中的。
我担心缺乏对组件运行时间和资源占用的控制,该示例只是实现了另一个线程,但据我所知,没有什么可以阻止这种类型的设计产生尽可能多的线程,好吧在您的程序允许的范围内。
我确实想到了诸如对象注入等方法,但是线程很奇怪,因为从组件的角度来看,它们是纯粹的“动作”,而不是“模型、状态、声明”,
任何帮助都会很棒。
I have recently been looking at code, specifically component oriented code that uses threads internally. Is this a bad practise. The code I looked at was from an F# example that showed the use of event based programming techniques. I can not post the code in case of copyright infringements, but it does spin up a thread of its own. Is this regarded as bad practise or is it feasible that code not written by yourself has full control of thread creation. I do point out that this code is not a visual component and is very much "built from scratch".
What are the best practises of component creation where threading would be helpful?
I am completely language agnostic on this, the f# example could have been in c# or python.
I am concerned about the lack of control over the components run time and hogging of resources, the example just implemented another thread, but as far as I can see there is nothing stopping this type of design from spawning as many threads as it wishes, well to the limit of what your program allows.
I did think of methods such as object injecting and so fourth, but threads are weird as they are from a component perspective pure "action" as opposed to "model, state, declarations"
any help would be great.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一个太笼统的问题,无法给出比“这取决于”更具体的答案:-)
在某些情况下,在组件中使用内部线程是完全有效的,而在某些情况下则不然。这必须根据具体情况来决定。但总的来说,由于线程确实使代码更加难以测试和维护,并且增加了微妙的、难以发现的错误的机会,所以只有当有真正决定性的理由使用它们时,才应该谨慎使用它们。
线程的合法使用的一个例子是工作线程,其中处理事件的组件启动一个需要很长时间才能执行的操作(例如冗长的计算、Web 请求或大量文件) I/O),并生成一个单独的线程来完成这项工作,以便控制权可以立即返回到界面以处理进一步的用户输入。如果没有工作线程,UI 将在很长一段时间内完全没有响应,这通常会让用户生气。
另一个例子是冗长的计算/过程,它非常适合并行执行,即它由许多大小或多或少相似的较小的独立任务组成。如果有很强的性能要求,那么使用工作线程池以并发方式执行各个任务确实有意义。许多语言为此类设计提供高级支持。
请注意,组件通常也可以自由分配和使用任何其他类型的资源,从而以无数其他方式造成严重破坏 - 您是否担心组件会耗尽所有内存、耗尽可用文件句柄、保留端口等?其中许多可能会在系统内造成比产生额外线程更多的麻烦。
This is too general a question to bear any answer more specific than "it depends" :-)
There are cases when using internal threads within a component is completely valid, and there are cases when not. This has to be decided on a case by case basis. Overall, though, since threads do make the code much more difficult to test and maintain, and increase the chances of subtle, hard to find bugs, they should be used with caution, only when there is a really decisive reason to use them.
An example to the legitimate use of threads is a worker thread, where a component handling an event starts an action which takes a long time to execute (such as a lengthy computation, a web request, or extensive file I/O), and spawns a separate thread to do the job, so that the control can be immediately returned to the interface to handle further user input. Without the worker thread, the UI would be totally unresponsive for a long time, which usually makes users angry.
Another example is a lengthy calculation/process which lends itself well to parallel execution, i.e. it consists of many smaller independent tasks of more or less similar size. If there are strong performance requirements, it does indeed make sense to execute the individual tasks in a concurrent fashion using a pool of worker threads. Many languages provide high level support for such designs.
Note that components are generally free to allocate and use any other kinds of resources too and thus wreak havoc in countless other ways - are you ever worried about a component eating up all memory, exhausting the available file handles, reserving ports etc.? Many of these can cause much more trouble globally within a system than spawning extra threads.
在组件/库中创建新线程没有任何问题。唯一的错误是它没有为 API/组件的使用者提供一种在必要时进行同步的方法。
There's nothing wrong about creating new threads in a component/library. The only thing wrong would be if it didn't give the consumer of the API/component a way to synchronize whenever necessary.
首先,你所说的组件的本质是什么?它是一个被某些不同代码使用的dll吗?它有什么作用?业务要求是什么?所有这些对于确定您是否确实需要担心并行性都是至关重要的。
其次,线程只是一种获得更好性能和响应能力的工具,因此在任何地方不惜一切代价避免使用线程听起来并不是一个明智的方法 - 线程对于某些业务需求当然至关重要。
第三,在比较 c# 和 f# 中的线程语义时,您必须记住它们本身是非常不同的野兽 - f# 隐式地使线程更安全,因为没有全局变量的概念,因此代码中的关键部分是一些东西在 f# 中比在 c# 中更容易避免。这让你作为一个开发者处于一个更好的位置,因为你不必处理内存块、锁、信号量等。
我想说,如果你的“组件”严重依赖线程,你可能需要考虑使用 c# 中的并行 FX,甚至使用 f#,因为它以更优雅的方式处理处理器时间切片和并行性(恕我直言)。
最后但并非最不重要的一点是,当您谈到在组件中使用线程来占用计算机资源时 - 请记住,编码线程本身并不一定会造成更高的资源影响 - 如果您这样做,您也可以轻松地对一个线程造成相同的损害不要正确地处理你的对象(未管理的),当然,当你在多个线程上犯同样的错误时,你可能会更快地得到 OutOfMemeory 异常......
First of all, what is the nature of component you are talking about? Is it a dll to be consumed by some different code? What does it do? What are the business requirements? All these are essential to determine if you do need to worry about parallelism or not.
Second of all, threading is just a tool to acheive better performance, responsivness so avoiding it at all cost everywhere does not sound like a smart approach - threading is certainly vital for some business needs.
Third of all, when comparing threading symantics in c# vs f#, you have to remember that those are very different beasts in theirselfs - f# implicitly makes threading safer to code as there is no notion of global variables hence the critical section in your code is something easier to eschew in f# than in c#. That puts your as a deleloper in a better place bc you dont have to deal with memoryblocks, locks, semaphores etc.
I would say if your 'component' relies heavily on threading you might want to consider using either the parallel FX in c# or even go with f# since it kind of approaches working with processer time slicing and parallelism in more elegant way (IMHO).
And last but not least, when you say about hogging up computer resources by using threading in your component - please remember that coding threads do not necessarily impose higher resource impact per se – you can just as easily do the same damage on one thread if you don’t dispose of your objects (unmaneged) properly, granted you might get OutOfMemeory Exception faster when you make the same mistake on several threads…