C# 中的 ThreadPool.QueueUserWorkItem()

2025 年 2 月 5 日 | 阅读 6 分钟

在本文中,我们将讨论 C# 中的 ThreadPool.QueueUserWorkItem()。C# 中的线程池是一个线程集合,可用于多种用途或后台任务。当请求到来时,它通常会转到线程池并询问是否有空闲线程。如果可能,将检索线程对象并执行任务。

什么是 C# 中的线程池及其用法?

为了理解 C# 中的线程池如何工作,让我们举一个例子。了解如何应用线程池后,我们将能够看到普通线程对象和线程池线程对象之间的性能基准。

步骤 1: 为了在 C# 语言中有效实现线程池,我们必须导入 Threading 命名空间,其中包含 ThreadPool 类,如下所示。 using System.Threading;

步骤 2: 导入 Threading 命名空间后,我们应该使用 ThreadPool 类,然后使用该类调用 QueueUserWorkItem 静态方法。此外,我们应该注意 QueueUserWorkItem 方法接受一个 WaitCallback 类型的对象作为参数。为了创建 WaitCallback 类对象,我们需要首先将我们希望在代码行中执行的方法的名称传递给它,如下所示。

QueueUserWorkItem 方法中,该函数被排队等待执行,并在从线程池中获取可用线程时执行。如果没有可用线程,它将排队等待一个线程空闲。这里,MyMethod 是我们希望由线程池成员线程实现的那个方法。

什么是 ThreadPool.QueueUserWorkItem()?

C# 中的 ThreadPool.QueueUserWorkItem() 方法用于将委托排队到线程池并将其在池中的指定线程(线程)上运行。它提供了一种便捷的机制,可以将主线程的工作转移到后台线程,而无需手动创建线程。

换句话说,线程池是一组托管线程,可用于并发执行任务。线程在线程池设置的环境中运行,有些人称之为工作线程。工作线程设计用于处理快速运行的任务。线程池的工作方式如下:启动前,线程池会创建一定数量的线程。然后将另一个任务发送到线程池队列,然后队列分配一个可用的线程来执行任务。因此,线程完成任务后,线程池会将线程返回到池中,并将其设置为准备执行下一个任务。

这有助于线程池避免为每个任务创建和销毁线程的开销,因为这在资源和时间方面成本很高。要创建线程池,我们使用 ThreadPool 类。ThreadPool 类带有 QueueUserWorkItem,用于将任务提交或调用到线程池或工作线程。QueueUserWorkItem 指的是将给定方法排队等待执行的方法。这意味着当线程池中的线程准备好执行时,可运行的方法就会发生。

语法

它的语法如下:

参数

callBack:一个 WaitCallback,是对要执行的方法的引用。

示例

让我们举一个例子来说明如何在 C# 中排队一个任务。

文件名:ThreadPool.cs

输出

 
Main thread processing.
Hello, the message from the thread pool.
The main thread is stopped.   

说明

此 C# 代码说明了 ThreadPool 类的功能,该类将任务排队以供执行。ThreadPool.QueueUserWorkItem(ThreadProcess) 方法将由 ThreadProcess 方法表示的任务添加到线程池中的某个线程将执行的任务列表中。此线程是主线程,在线程池中的某个线程处理该任务时,它仍在处理。

QueueUserWorkItem(WaitCallback, Object)

排队定义了一个要执行的方法,并指示一个将在该方法中用作参数的对象。当有来自线程池的线程时,该方法将被调用。

语法

它具有以下语法:

参数

  • callBack:WaitCallback,使用 WaitCallback 来执行此方法。
  • State:Object,包含要由方法处理的数据的对象。

异常

  • NotSupportedException:宿主引擎托管了公共语言运行时 (CLR),并且宿主不支持此操作。
  • ArgumentNullException:CallBack 为 null。

示例

文件名:WaitCallback.cs

输出

 
Launching of 6 tasks...
The Thread 5 has started...
The Thread 3 has started...
The Thread 1 has started...
The Thread 1 result has been calculated...
The Thread 5 result has been calculated...
The Thread 3 result has been calculated...
The Thread 0 has started...
The Thread 4 has started...
The Thread 2 has started...
The Thread 0 result has been calculated...
The Thread 2 result has been calculated...
The Thread 4 result has been calculated...
The calculations are completed.
Fib(17) = 1597
Fib(14) = 377
Fib(16) = 987
Fib(12) = 144
Fib(16) = 987
Fib(12) = 144   

说明

上述程序应用 .NET 框架的线程池以并行方式生成 10 到 20 的斐波那契数列结果。计算每个斐波那契结果的线程由 Fib 类创建,该类包含一个名为 threadPoolCallbackMethod 的方法,该方法执行计算。斐波那契数列是一个数字序列 0,1,1,2,3... 等,其中创建了与每个斐波那契数相似的对象。最后,将 ThreadPoolCallbackMethod 作为参数传递给 QueueUserWorkItem 方法,并将在线程池中可用的某个线程上执行它。

结论

  • C# 中的 ThreadPool 类包含处理线程池的方法。第二种方法是 QueueUserWorkItem,它实现了一个委托并将其放入线程池线程队列以供执行。该方法使用 WaitCallback 对象作为参数,并指定将在此时运行的方法。
  • 通过 ThreadPool.QueueUserWorkItem(new WaitCallback(MyMethod)) 命令,我们将 MyMethod 特定方法的执行排队,以随机分配给线程池中的某个线程。如果没有线程,该方法将排队等待直到有一个可用线程。
  • 线程池的一个主要好处是它消除了为每个任务创建和销毁新线程的需要,从而节省了时间和资源。通过维护一组随时待命的工作线程并持续执行任务,可以确保更高的性能。
  • 在需要时,我们可以应用线程池和 QueueUserWorkItem 方法来加速多个后台任务的并发执行。