异步委托与线程/ ThreadPool?

cla*_*aws 33 .net c# multithreading

我需要执行3个并行任务,在完成每个任务后,他们应该调用相同的函数来打印出结果.

我不明白.net为什么我们有异步调用(delegate.BeginInvoke()和delegate.EndInvoke())以及Thread类?

我有点困惑哪一个用?现在在这种特殊情况下,我应该使用Asychronous调用还是Thread类?

我正在使用C#.

cla*_*aws 44

1.异步代表

当您有工作项目应该在后台处理并且在完成时您关心时,将使用异步调用.

BackgroundWorker与后台线程

2. BackgroundWorker

  • 如果您有一个在后台运行并需要与UI交互的任务,请使用BackgroundWorker .如果你在完成任务时不在乎,就使用它.通过基于事件的模型自动处理对UI线程进行编组和方法调用的任务.
  • 如果(1)您的程序集尚未引用System.Windows.Form程序集,(2)您需要将该线程作为前台线程,或(3)您需要操纵线程优先级,请避免使用BackgroundWorker.

3. ThreadPool

  • 在需要效率时使用ThreadPool线程.ThreadPool有助于避免与创建,启动和停止线程相关的开销.
  • 如果(1)任务在应用程序的生命周期内运行,则避免使用ThreadPool,(2)您需要将线程作为前台线程,(3)您需要操纵线程优先级,或者(4)您需要线程拥有固定的身份(中止,暂停,发现).

4.线程类

  • 将Thread类用于长时间运行的任务,当需要正式线程模型提供的功能时,例如,在前台线程和后台线程之间进行选择,调整线程优先级,对线程执行进行细粒度控制等.

  • 使用线程类(#4)而不是任何基于线程池的替代方法(#1-#3)的另一种情况:如果使用任何在线程静态字段中存储对象引用的类,那些直接或间接目标除非或直到删除引用或包含它们的线程退出,否则引用将不符合垃圾回收的条件.如果线程静态引用存储在线程池线程中,则它们可能会无限期地保留在那里,可能会造成大量内存泄漏. (2认同)
  • 这似乎是最好的答案,但是有点担心没有人提到ThreadPool饱和度或者建议运行委托的时间会影响你的决定.ThreadPool/TaskPool用于在后台线程上快速完成工作,但应限制在少于50-150ms的工作中.繁重的工作(即超过150毫秒)会导致线程池饱和,然后在ThreadPool调整大小时可能会出现令人讨厌的500毫秒延迟. (2认同)

Jon*_*len 12

我不明白.net为什么我们有异步调用(delegate.BeginInvoke()和delegate.EndInvoke())以及Thread类?

  • 当您有工作项目应该在后台处理并且在完成时您关心时,将使用异步调用.

  • 线程池用于当您拥有应在后台处理的工作项时,并且在完成时您并不在意.

  • 线程用于做永不完成的东西.

例子:

如果要从磁盘读取大文件而不想阻止GUI线程,请使用异步调用.

如果您在后台懒惰地编写一个或多个文件,请使用线程池.

如果每隔几秒轮询文件系统以查找更改的内容,请使用线程.


Fly*_*wat 5

异步方法实质上抽象了工作实际处理的方式.它可能会产生一个新的进程,它可能在一个单独的线程中执行......没关系.

重要的是你在说:

  1. 启动时运行此代码.
  2. 完成后运行此代码.

如果给出了选择,我将使用API​​异步方法,而不是每次都实现我自己的线程机制.框架开发人员为您做了艰苦的工作,为什么要重新发明轮子.