ThreadPool.QueueUserWorkItem 方法

定义

将方法排入队列以便执行。 此方法在有线程池线程变得可用时执行。

重载

QueueUserWorkItem(WaitCallback)

将方法排入队列以便执行。 此方法在有线程池线程变得可用时执行。

QueueUserWorkItem(WaitCallback, Object)

将方法排入队列以便执行,并指定包含该方法所用数据的对象。 此方法在有线程池线程变得可用时执行。

QueueUserWorkItem<TState>(Action<TState>, TState, Boolean)

Action<T> 委托指定的方法排入队列以便执行,并提供该方法使用的数据。 此方法在有线程池线程变得可用时执行。

QueueUserWorkItem(WaitCallback)

Source:
ThreadPoolWorkQueue.cs
Source:
ThreadPoolWorkQueue.cs
Source:
ThreadPoolWorkQueue.cs

将方法排入队列以便执行。 此方法在有线程池线程变得可用时执行。

public:
 static bool QueueUserWorkItem(System::Threading::WaitCallback ^ callBack);
public static bool QueueUserWorkItem (System.Threading.WaitCallback callBack);
static member QueueUserWorkItem : System.Threading.WaitCallback -> bool
Public Shared Function QueueUserWorkItem (callBack As WaitCallback) As Boolean

参数

callBack
WaitCallback

一个 WaitCallback,表示要执行的方法。

返回

如果此方法成功排队,则为 true;如果无法将该工作项排队,则引发 NotSupportedException

例外

callBacknull

承载公共语言运行时 (CLR) 的宿主不支持此操作。

示例

以下示例使用 QueueUserWorkItem(WaitCallback) 方法重载将任务(由 ThreadProc 方法表示)排队,以在线程可用时执行。 此重载未提供任何任务信息。 因此,方法可用的 ThreadProc 信息仅限于该方法所属的对象。

using namespace System;
using namespace System::Threading;

ref class Example
{
public:

   // This thread procedure performs the task.
   static void ThreadProc(Object^ stateInfo)
   {
      
      // No state object was passed to QueueUserWorkItem, so stateInfo is 0.
      Console::WriteLine( "Hello from the thread pool." );
   }
};

int main()
{
   // Queue the task.
   ThreadPool::QueueUserWorkItem(gcnew WaitCallback(Example::ThreadProc));

   Console::WriteLine("Main thread does some work, then sleeps.");
   
   Thread::Sleep(1000);
   Console::WriteLine("Main thread exits.");
   return 0;
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.
using System;
using System.Threading;

public class Example 
{
    public static void Main() 
    {
        // Queue the task.
        ThreadPool.QueueUserWorkItem(ThreadProc);
        Console.WriteLine("Main thread does some work, then sleeps.");
        Thread.Sleep(1000);

        Console.WriteLine("Main thread exits.");
    }

    // This thread procedure performs the task.
    static void ThreadProc(Object stateInfo) 
    {
        // No state object was passed to QueueUserWorkItem, so stateInfo is null.
        Console.WriteLine("Hello from the thread pool.");
    }
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.
Imports System.Threading

Public Module Example
    Public Sub Main()
        ' Queue the work for execution.
        ThreadPool.QueueUserWorkItem(AddressOf ThreadProc)
        
        Console.WriteLine("Main thread does some work, then sleeps.")

        Thread.Sleep(1000)

        Console.WriteLine("Main thread exits.")
    End Sub

    ' This thread procedure performs the task.
    Sub ThreadProc(stateInfo As Object)
        ' No state object was passed to QueueUserWorkItem, so stateInfo is null.
        Console.WriteLine("Hello from the thread pool.")
    End Sub
End Module
' The example displays output like the following:
'       Main thread does some work, then sleeps.
'       Hello from the thread pool.
'       Main thread exits.

注解

可以将排队方法所需的数据放在定义方法的类的实例字段中,也可以使用 QueueUserWorkItem(WaitCallback, Object) 接受包含必要数据的 对象的重载。

注意

Visual Basic 用户可以省略 WaitCallback 构造函数,只需在 AddressOf 将回调方法 QueueUserWorkItem传递给 时使用 运算符。 Visual Basic 自动调用正确的委托构造函数。

属性值 Thread.CurrentPrincipal 传播到使用 QueueUserWorkItem 方法排队的工作线程。

另请参阅

适用于

QueueUserWorkItem(WaitCallback, Object)

Source:
ThreadPoolWorkQueue.cs
Source:
ThreadPoolWorkQueue.cs
Source:
ThreadPoolWorkQueue.cs

将方法排入队列以便执行,并指定包含该方法所用数据的对象。 此方法在有线程池线程变得可用时执行。

public:
 static bool QueueUserWorkItem(System::Threading::WaitCallback ^ callBack, System::Object ^ state);
public static bool QueueUserWorkItem (System.Threading.WaitCallback callBack, object? state);
public static bool QueueUserWorkItem (System.Threading.WaitCallback callBack, object state);
static member QueueUserWorkItem : System.Threading.WaitCallback * obj -> bool
Public Shared Function QueueUserWorkItem (callBack As WaitCallback, state As Object) As Boolean

参数

callBack
WaitCallback

WaitCallback,它表示要执行的方法。

state
Object

包含方法所用数据的对象。

返回

如果此方法成功排队,则为 true;如果无法将该工作项排队,则引发 NotSupportedException

例外

承载公共语言运行时 (CLR) 的宿主不支持此操作。

callBacknull

示例

以下示例使用 .NET 线程池来计算 Fibonacci 20 到 40 之间的五个数字的结果。 每个 Fibonacci 结果都由 Fibonacci 类表示,该类提供一个名为 ThreadPoolCallback 的方法,用于执行计算。 创建表示每个 Fibonacci 值的对象,并将 ThreadPoolCallback 方法传递给 QueueUserWorkItem,它分配池中的一个可用线程来执行此方法。

由于每个对象都有 Fibonacci 一个半随机值用于计算,并且每个线程都将争用处理器时间,因此无法提前知道计算所有五个结果需要多长时间。 这就是在构造期间为每个 Fibonacci 对象传递 ManualResetEvent 类的一个实例的原因。 每个对象在计算完成后向提供的事件对象发出信号,这样主线程就可以阻止执行 WaitAll ,直到所有五 Fibonacci 个对象都计算出一个结果。 然后 Main 方法会显示每个 Fibonacci 结果。

using namespace System;
using namespace System::Threading;

public ref class Fibonacci
{
private:
    ManualResetEvent^ _doneEvent;

    int Calculate(int n)
    {
        if (n <= 1)
        {
            return n;
        }
        return Calculate(n - 1) + Calculate(n - 2);
    }

public:
    
    int ID;
    int N;
    int FibOfN;

    Fibonacci(int id, int n, ManualResetEvent^ doneEvent)
    {
        ID = id;
        N = n;
        _doneEvent = doneEvent;
    }

    void Calculate()
    {
        FibOfN = Calculate(N);
    }

    void SetDone()
    {
        _doneEvent->Set();
    }
};

public ref struct Example
{
public:

    static void ThreadProc(Object^ stateInfo)
    {
        Fibonacci^ f = dynamic_cast<Fibonacci^>(stateInfo);
        Console::WriteLine("Thread {0} started...", f->ID);
        f->Calculate();
        Console::WriteLine("Thread {0} result calculated...", f->ID);
        f->SetDone();
    }
};


void main()
{
    const int FibonacciCalculations = 5;

    array<ManualResetEvent^>^ doneEvents = gcnew array<ManualResetEvent^>(FibonacciCalculations);
    array<Fibonacci^>^ fibArray = gcnew array<Fibonacci^>(FibonacciCalculations);
    Random^ rand = gcnew Random();

    Console::WriteLine("Launching {0} tasks...", FibonacciCalculations);

    for (int i = 0; i < FibonacciCalculations; i++)
    {
        doneEvents[i] = gcnew ManualResetEvent(false);
        Fibonacci^ f = gcnew Fibonacci(i, rand->Next(20, 40), doneEvents[i]);
        fibArray[i] = f;
        ThreadPool::QueueUserWorkItem(gcnew WaitCallback(Example::ThreadProc), f);
    }

    WaitHandle::WaitAll(doneEvents);
    Console::WriteLine("All calculations are complete.");

    for (int i = 0; i < FibonacciCalculations; i++)
    {
        Fibonacci^ f = fibArray[i];
        Console::WriteLine("Fibonacci({0}) = {1}", f->N, f->FibOfN);
    }
}
// Output is similar to:
// Launching 5 tasks...
// Thread 3 started...
// Thread 2 started...
// Thread 1 started...
// Thread 0 started...
// Thread 4 started...
// Thread 4 result calculated...
// Thread 1 result calculated...
// Thread 2 result calculated...
// Thread 0 result calculated...
// Thread 3 result calculated...
// All calculations are complete.
// Fibonacci(30) = 832040
// Fibonacci(24) = 46368
// Fibonacci(26) = 121393
// Fibonacci(36) = 14930352
// Fibonacci(20) = 6765
using System;
using System.Threading;

public class Fibonacci
{
    private ManualResetEvent _doneEvent;

    public Fibonacci(int n, ManualResetEvent doneEvent)
    {
        N = n;
        _doneEvent = doneEvent;
    }

    public int N { get; }

    public int FibOfN { get; private set; }

    public void ThreadPoolCallback(Object threadContext)
    {
        int threadIndex = (int)threadContext;
        Console.WriteLine($"Thread {threadIndex} started...");
        FibOfN = Calculate(N);
        Console.WriteLine($"Thread {threadIndex} result calculated...");
        _doneEvent.Set();
    }

    public int Calculate(int n)
    {
        if (n <= 1)
        {
            return n;
        }
        return Calculate(n - 1) + Calculate(n - 2);
    }
}

public class ThreadPoolExample
{
    static void Main()
    {
        const int FibonacciCalculations = 5;

        var doneEvents = new ManualResetEvent[FibonacciCalculations];
        var fibArray = new Fibonacci[FibonacciCalculations];
        var rand = new Random();

        Console.WriteLine($"Launching {FibonacciCalculations} tasks...");
        for (int i = 0; i < FibonacciCalculations; i++)
        {
            doneEvents[i] = new ManualResetEvent(false);
            var f = new Fibonacci(rand.Next(20, 40), doneEvents[i]);
            fibArray[i] = f;
            ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
        }

        WaitHandle.WaitAll(doneEvents);
        Console.WriteLine("All calculations are complete.");

        for (int i = 0; i < FibonacciCalculations; i++)
        {
            Fibonacci f = fibArray[i];
            Console.WriteLine($"Fibonacci({f.N}) = {f.FibOfN}");
        }
    }
}
// The output is similar to:
// Launching 5 tasks...
// Thread 3 started...
// Thread 4 started...
// Thread 2 started...
// Thread 1 started...
// Thread 0 started...
// Thread 2 result calculated...
// Thread 3 result calculated...
// Thread 4 result calculated...
// Thread 1 result calculated...
// Thread 0 result calculated...
// All calculations are complete.
// Fibonacci(35) = 9227465
// Fibonacci(27) = 196418
// Fibonacci(25) = 75025
// Fibonacci(25) = 75025
// Fibonacci(27) = 196418
Imports System.Threading

Public Class Fibonacci
    Private _doneEvent As ManualResetEvent

    Public Sub New(n As Integer, doneEvent As ManualResetEvent)
        Me.N = n
        _doneEvent = doneEvent
    End Sub

    Public ReadOnly Property N As Integer
    Public Property FibOfN As Integer

    Public Sub ThreadPoolCallback(threadContext As Object)
        Dim threadIndex As Integer = CType(threadContext, Integer)
        Console.WriteLine($"Thread {threadIndex} started...")
        FibOfN = Calculate(N)
        Console.WriteLine($"Thread {threadIndex} result calculated...")
        _doneEvent.Set()
    End Sub

    Public Function Calculate(n As Integer) As Integer
        If (n <= 1) Then
            Return n
        End If
        Return Calculate(n - 1) + Calculate(n - 2)
    End Function
End Class

Public Class ThreadPoolExample

    <MTAThread>
    Public Shared Sub Main()

        Const FibonacciCalculations As Integer = 5

        Dim doneEvents(FibonacciCalculations - 1) As ManualResetEvent
        Dim fibArray(FibonacciCalculations - 1) As Fibonacci
        Dim rand As Random = New Random()

        Console.WriteLine($"Launching {FibonacciCalculations} tasks...")

        For i As Integer = 0 To FibonacciCalculations - 1
            doneEvents(i) = New ManualResetEvent(False)
            Dim f As Fibonacci = New Fibonacci(rand.Next(20, 40), doneEvents(i))
            fibArray(i) = f
            ThreadPool.QueueUserWorkItem(AddressOf f.ThreadPoolCallback, i)
        Next

        WaitHandle.WaitAll(doneEvents)
        Console.WriteLine("All calculations are complete.")

        For i As Integer = 0 To FibonacciCalculations - 1
            Dim f As Fibonacci = fibArray(i)
            Console.WriteLine($"Fibonacci({f.N}) = {f.FibOfN}")
        Next
    End Sub
End Class
' Output is similar to
' Launching 5 tasks...
' Thread 1 started...
' Thread 2 started...
' Thread 3 started...
' Thread 4 started...
' Thread 0 started...
' Thread 4 result calculated...
' Thread 2 result calculated...
' Thread 3 result calculated...
' Thread 0 result calculated...
' Thread 1 result calculated...
' All calculations are complete.
' Fibonacci(37) = 24157817
' Fibonacci(38) = 39088169
' Fibonacci(29) = 514229
' Fibonacci(32) = 2178309
' Fibonacci(23) = 28657

注解

如果回调方法需要复杂数据,则可以定义一个类来包含数据。

注意

Visual Basic 用户可以省略 WaitCallback 构造函数,只需在 AddressOf 将回调方法 QueueUserWorkItem传递给 时使用 运算符。 Visual Basic 自动调用正确的委托构造函数。

另请参阅

适用于

QueueUserWorkItem<TState>(Action<TState>, TState, Boolean)

Source:
ThreadPoolWorkQueue.cs
Source:
ThreadPoolWorkQueue.cs
Source:
ThreadPoolWorkQueue.cs

Action<T> 委托指定的方法排入队列以便执行,并提供该方法使用的数据。 此方法在有线程池线程变得可用时执行。

public:
generic <typename TState>
 static bool QueueUserWorkItem(Action<TState> ^ callBack, TState state, bool preferLocal);
public static bool QueueUserWorkItem<TState> (Action<TState> callBack, TState state, bool preferLocal);
static member QueueUserWorkItem : Action<'State> * 'State * bool -> bool
Public Shared Function QueueUserWorkItem(Of TState) (callBack As Action(Of TState), state As TState, preferLocal As Boolean) As Boolean

类型参数

TState

state 的元素类型。

参数

callBack
Action<TState>

Action<T>,它表示要执行的方法。

state
TState

包含方法所用数据的对象。

preferLocal
Boolean

true 表示首选在靠近当前线程的队列中对工作项进行排队;false 则表示首选将工作项排队到线程池的共享队列中。

返回

如果此方法成功排队,则为 true;如果无法将该工作项排队,则引发 NotSupportedException

适用于