Поделиться через


ThreadPool.QueueUserWorkItem Метод

Определение

Помещает метод в очередь на выполнение. Метод выполняется, когда становится доступен поток из пула потоков.

Перегрузки

QueueUserWorkItem(WaitCallback)

Помещает метод в очередь на выполнение. Метод выполняется, когда становится доступен поток из пула потоков.

QueueUserWorkItem(WaitCallback, Object)

Помещает метод в очередь на выполнение и указывает объект, содержащий данные для использования методом. Метод выполняется, когда становится доступен поток из пула потоков.

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

Помещает метод, определенный делегатом Action<T>, в очередь на выполнение и указывает данные для этого метода. Метод выполняется, когда становится доступен поток из пула потоков.

QueueUserWorkItem(WaitCallback)

Исходный код:
ThreadPoolWorkQueue.cs
Исходный код:
ThreadPoolWorkQueue.cs
Исходный код:
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.

Исключения

callBack имеет значение null.

Среда 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)

Исходный код:
ThreadPoolWorkQueue.cs
Исходный код:
ThreadPoolWorkQueue.cs
Исходный код:
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 является размещенной, а основное приложение не поддерживает это действие.

callBack имеет значение null.

Примеры

В следующем примере пул потоков .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)

Исходный код:
ThreadPoolWorkQueue.cs
Исходный код:
ThreadPoolWorkQueue.cs
Исходный код:
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.

Применяется к