تجمع مؤشر ترابط مدارة

ThreadPoolتوفر فئة تطبيق الخاص بك بتجمع مؤشرات ترابط العاملين التي تتم إدارتها من قبل النظام، مما يسمح لك إلى التركيز تشغيل مهام تطبيق بدلاً من مؤشر ترابط. مدارة إذا كان لديك المهام القصيرة التي تتطلب خلفية معالجة تجمع عمليات جزئية التي تمت إدارتها هو طريقة سهلة للاستفادة من مؤشرات ترابط متعددة.

ملاحظةملاحظة

بدءاً من .NET Framework الإصدار 2.0 Service Pack 1، سرعة بتجمع مؤشرات الترابط هو تحسين في ثلاث نواح رئيسية تم تصنيفها اختناقات في الإصدارات السابقة ل .NET Framework: مهام قائمة الانتظار، إرسال مؤشر ترابط في تجمع عمليات جزئية، و إرسال عمليات جزئية إكمال الادخال/الاخراج.إلى استخدم هذه الوظيفة، يجب توجيه تطبيق الخاص بك NET Framework. الإصدار 3.5أو الإصدار الأحدث.

مهام الخلفية التي تتفاعل مع واجهة مستخدم، الإصدار 2.0 من برنامج.NET Framework كما يوفر BackgroundWorkerمرفوعة فئة، والذي يتصل باستخدام الأحداث تشغيل مؤشر ترابط واجهة مستخدم.

يستخدم إطار عمل.NET مؤشر ترابط تجمع مؤشر ترابط s الكثير من الأغراض، بما في ذلك إكمال الادخال/الاخراج غير المتزامن، انتظر رد الاتصال لجهاز ضبط الوقت، مسجَّل العمليات، واستدعاء أسلوب متزامن استخدام التفويضات و System.Netالاتصالات مأخذ التوصيل.

عند عدم استخدام إلى مؤشر ترابط تجمع مؤشرات الترابط

هناك عدة سيناريوهات في عليها هو المناسبة لإنشاء وإدارة عمليات جزئية الخاصة بك بدلاً من استخدام مؤشرات ترابط تجمع مؤشر ترابط:

  • يتطلب مؤشر ترابط مقدمة.

  • طلبت مؤشر ترابط إلى لها أولوية معين.

  • لديك المهام التي تسبب مؤشر ترابط إلى كتلة لفترات زمنية طويلة. لقد تجمع عمليات جزئية الحد الأقصى لعدد عمليات جزئية، حيث قد عددا كبيرا من مؤشرات ترابط تجمع مؤشر ترابط المحظورة تمنع البدء المهام.

  • تحتاج إلى عمليات جزئية في وضع إلى الحيز مؤشر ترابط مفرد. لكافة ThreadPoolعمليات جزئية في شقة ذات مؤشرات ترابط متعددة.

  • تحتاج إلى تحتوي هوية مستقرة المقترن مع مؤشر الترابط، أو إلى تعيينه مؤشر ترابط إلى مهمة.

الصفات المميزة تجمع مؤشر ترابط

مؤشرات ترابط تجمع مؤشر ترابط هي عمليات جزئية في الخلفية. انظر المقدمة و عمليات جزئية الخلفية كل مؤشر ترابط يستخدم الحجم مكدس الذاكرة المؤقتة الافتراضية، يتم تشغيل على الأفضلية الافتراضية، و هو في شقة ذات مؤشرات ترابط متعددة.

هناك هو تجمع مؤشر ترابط واحد فقط في كل عملية.

الاستثناءات في تجمع مؤشر ترابط عمليات جزئية

لم تتم معالجته استثناءات في تجمع عمليات جزئية إنهاء عمليات جزئية في العملية. هناك ثلاثة استثناءات إلى هذه قاعدة:

  • ThreadAbortExceptionهو تم طرح في مؤشر ترابط تجمع مؤشر ترابط، لأن Abortتم استدعاء.

  • AppDomainUnloadedExceptionهو طرح في مؤشر ترابط تجمع مؤشر ترابط، وذلك لأنه يتم الآن إلغاء تحميل مجال تطبيق.

  • اللغة الشائعة وقت التشغيل أو إنهاء عملية مضيف مؤشر ترابط.

لمزيد من المعلومات، راجع الاستثناءات في مدارة عمليات جزئية.

ملاحظةملاحظة

في إصدارات.NET Framework 1.0 و 1.1، اللغة الشائعة وقت التشغيل صمت يعوض الاستثناءات غير المعالجة في مؤشرات ترابط تجمع مؤشر ترابط.وهذا قد يلحق الولاية تطبيق و أخيرا تتسبب التطبيقات توقف، والذي قد يكون من الصعب جداً يصحح.

الحد الأقصى رقم of مؤشر ترابط Pool عمليات جزئية

The رقم of العمليات that can be queued إلى the مؤشر ترابط pool هو limited فقط بواسطة متوفر ذاكرة; however, the مؤشر ترابط pool limits the رقم of العمليات جزئية that can be نشط في the عملية simultaneously. بشكل افتراضي، فإن الحد الأقصى هو 250 مؤشرات ترابط العاملين في CPU ومؤشرات الترابط إكمال الادخال/الاخراج 1000.

You can عنصر تحكم the الحد الأقصى رقم of عمليات جزئية بواسطة using the GetMaxThreads و SetMaxThreads وظائف.

ملاحظةملاحظة

في the .NET Framework versions 1.0 و 1.1, the الحجم of the مؤشر ترابط pool cannot be التعيين من مدارة تعليمات برمجية.تعليمات برمجية that hosts the وقت تشغيل اللغة العامة can التعيين the الحجم using CorSetMaxThreads, defined في mscoree.h.

الحد الأدنى رقم of خاملة عمليات جزئية

The مؤشر ترابط pool also maintains a الحد الأدنى رقم of متوفر عمليات جزئية, even when الجميع عمليات جزئية are خاملة, so that queued tasks can يبدأ immediately. خاملة عمليات جزئية في excess of this الحد الأدنى are منتهي إلى حفظ النظام موارد. بواسطة الافتراضي, واحد خاملة مؤشر ترابط هو maintained per processor.

The مؤشر ترابط pool has a built-في تأخير (half a ثانية في the .NET الإصدار إطار العمل 2.0) قبل البدء جديد خاملة عمليات جزئية. If your تطبيق periodically starts many tasks في a قصير الوقت, a مربع متوسط زيادة في the رقم of خاملة عمليات جزئية can produce a significant زيادة في throughput. إعداد the رقم of خاملة عمليات جزئية too عالي consumes النظام موارد needlessly.

You can عنصر تحكم the رقم of خاملة عمليات جزئية maintained بواسطة the مؤشر ترابط pool بواسطة using the GetMinThreads و SetMinThreads وظائف.

ملاحظةملاحظة

في the .NET الإصدار إطار العمل 1.0, the الحد الأدنى رقم of خاملة عمليات جزئية cannot be التعيين.

Skipping الأمان Checks

The مؤشر ترابط pool also provides the ThreadPool.UnsafeQueueUserWorkItem و ThreadPool.UnsafeRegisterWaitForSingleObject وظائف. استخدم these وظائف فقط when you are certain that the caller's مكدس هو irrelevant إلى أي الأمان checks performed during the execution of the queued مهمة. QueueUserWorkItemو RegisterWaitForSingleObject كلاهما يلتقط the caller's مكدس, which هو merged في the مكدس of the مؤشر ترابط pool مؤشر ترابط when the مؤشر ترابط begins إلى ينفذ a مهمة. If a الأمان فحص هو مطلوب, the entire مكدس must be محدد. Although the فحص provides safety, it also has a الأداء cost.

Using the مؤشر ترابط Pool

استخدام تجمع مؤشرات الترابط باستدعاء ThreadPool.QueueUserWorkItemمن تعليمات برمجية مُدارة (أو CorQueueUserWorkItemمن تعليمات برمجية غير مُدارة) WaitCallbackتفويض التي تمثل الطريقة التي تنفذ مهمة. يمكنك أيضا قائمة الانتظار عناصر العمل التي تتعلق إلى عملية انتظار باستخدام ThreadPool.RegisterWaitForSingleObjectالأسلوب وتمرير WaitHandle، عند إليه صوت أو عند انقضاء المهلة، يرفع مكالمة إلى الأسلوب الذي يمثله WaitOrTimerCallbackالمفوض. في كلاهما الحالات، يستخدم تجمع مؤشرات الترابط بمؤشر ترابط الخلفية إلى استدعاء الأسلوب رد الاتصال.

أمثلة ThreadPool

الثلاثة تعليمات برمجية تبين الأمثلة التالية في QueueUserWorkItemو RegisterWaitForSingleObjectالأساليب.

قائمة انتظار المثال أول جداً بسيط مهمة، represented بواسطة ThreadProcالأسلوب، استخدام QueueUserWorkItemالأسلوب.

Imports System
Imports System.Threading

Public Class Example
    Public Shared Sub Main()
        ' Queue the task.
        ThreadPool.QueueUserWorkItem( _
            New WaitCallback(AddressOf ThreadProc))
        
        Console.WriteLine("Main thread does some work, then sleeps.")
        ' If you comment out the Sleep, the main thread exits before
        ' the thread pool task runs.  The thread pool uses background
        ' threads, which do not keep the application running.  (This
        ' is a simple example of a race condition.)
        Thread.Sleep(1000)

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

    ' This thread procedure performs the task.
    Shared 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 Class
using System;
using System.Threading;
public class Example {
    public static void Main() {
        // Queue the task.
        ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
        
        Console.WriteLine("Main thread does some work, then sleeps.");
        // If you comment out the Sleep, the main thread exits before
        // the thread pool task runs.  The thread pool uses background
        // threads, which do not keep the application running.  (This
        // is a simple example of a race condition.)
        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.");
    }
}

تزويد بيانات مهمة ل QueueUserWorkItem

يستخدم المثال التالي رمز QueueUserWorkItemأسلوب إلى قائمة الانتظار مهمة وقم بكتابة بيانات للمهمة.

Imports System
Imports System.Threading
' TaskInfo holds state information for a task that will be
' executed by a ThreadPool thread.
Public Class TaskInfo
    ' State information for the task.  These members
    ' can be implemented as read-only properties, read/write
    ' properties with validation, and so on, as required.
    Public Boilerplate As String
    Public Value As Integer

    ' Public constructor provides an easy way to supply all
    ' the information needed for the task.
    Public Sub New(text As String, number As Integer)
        Boilerplate = text
        Value = number
    End Sub
End Class

Public Class Example
    Public Shared Sub Main()
        ' Create an object containing the information needed
        ' for the task.
        Dim ti As New TaskInfo("This report displays the number {0}.", 42)

        ' Queue the task and data.
        If ThreadPool.QueueUserWorkItem( _
            New WaitCallback(AddressOf ThreadProc), ti) Then
        
            Console.WriteLine("Main thread does some work, then sleeps.")

            ' If you comment out the Sleep, the main thread exits before
            ' the ThreadPool task has a chance to run.  ThreadPool uses 
            ' background threads, which do not keep the application 
            ' running.  (This is a simple example of a race condition.)
            Thread.Sleep(1000)

            Console.WriteLine("Main thread exits.")
        Else
            Console.WriteLine("Unable to queue ThreadPool request.")
        End If
    End Sub

    ' The thread procedure performs the independent task, in this case
    ' formatting and printing a very simple report.
    '
    Shared Sub ThreadProc(stateInfo As Object)
        Dim ti As TaskInfo = CType(stateInfo, TaskInfo)
        Console.WriteLine(ti.Boilerplate, ti.Value)
    End Sub
End Class
using System;
using System.Threading;

// TaskInfo holds state information for a task that will be
// executed by a ThreadPool thread.
public class TaskInfo {
    // State information for the task.  These members
    // can be implemented as read-only properties, read/write
    // properties with validation, and so on, as required.
    public string Boilerplate;
    public int Value;

    // Public constructor provides an easy way to supply all
    // the information needed for the task.
    public TaskInfo(string text, int number) {
        Boilerplate = text;
        Value = number;
    }
}

public class Example {
    public static void Main() {
        // Create an object containing the information needed
        // for the task.
        TaskInfo ti = new TaskInfo("This report displays the number {0}.", 42);

        // Queue the task and data.
        if (ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), ti)) {    
            Console.WriteLine("Main thread does some work, then sleeps.");

            // If you comment out the Sleep, the main thread exits before
            // the ThreadPool task has a chance to run.  ThreadPool uses 
            // background threads, which do not keep the application 
            // running.  (This is a simple example of a race condition.)
            Thread.Sleep(1000);

            Console.WriteLine("Main thread exits.");
        }
        else {
            Console.WriteLine("Unable to queue ThreadPool request."); 
        }
    }

    // The thread procedure performs the independent task, in this case
    // formatting and printing a very simple report.
    //
    static void ThreadProc(Object stateInfo) {
        TaskInfo ti = (TaskInfo) stateInfo;
        Console.WriteLine(ti.Boilerplate, ti.Value); 
    }
}

RegisterWaitForSingleObject

يلي مثال يوضح العديد من ميزات مؤشر الترابط.

Imports System
Imports System.Threading

' TaskInfo contains data that will be passed to the callback
' method.
Public Class TaskInfo
    public Handle As RegisteredWaitHandle = Nothing
    public OtherInfo As String = "default"
End Class

Public Class Example
    Public Shared Sub Main()
        ' The main thread uses AutoResetEvent to signal the
        ' registered wait handle, which executes the callback
        ' method.
        Dim ev As New AutoResetEvent(false)

        Dim ti As New TaskInfo()
        ti.OtherInfo = "First task"
        ' The TaskInfo for the task includes the registered wait
        ' handle returned by RegisterWaitForSingleObject.  This
        ' allows the wait to be terminated when the object has
        ' been signaled once (see WaitProc).
        ti.Handle = ThreadPool.RegisterWaitForSingleObject( _
            ev, _
            New WaitOrTimerCallback(AddressOf WaitProc), _
            ti, _
            1000, _
            false _
        )

        ' The main thread waits about three seconds, to demonstrate 
        ' the time-outs on the queued task, and then signals.
        Thread.Sleep(3100)
        Console.WriteLine("Main thread signals.")
        ev.Set()

        ' The main thread sleeps, which should give the callback
        ' method time to execute.  If you comment out this line, the
        ' program usually ends before the ThreadPool thread can execute.
        Thread.Sleep(1000)
        ' If you start a thread yourself, you can wait for it to end
        ' by calling Thread.Join.  This option is not available with 
        ' thread pool threads.
    End Sub
   
    ' The callback method executes when the registered wait times out,
    ' or when the WaitHandle (in this case AutoResetEvent) is signaled.
    ' WaitProc unregisters the WaitHandle the first time the event is 
    ' signaled.
    Public Shared Sub WaitProc(state As Object, timedOut As Boolean)
        ' The state object must be cast to the correct type, because the
        ' signature of the WaitOrTimerCallback delegate specifies type
        ' Object.
        Dim ti As TaskInfo = CType(state, TaskInfo)

        Dim cause As String = "TIMED OUT"
        If Not timedOut Then
            cause = "SIGNALED"
            ' If the callback method executes because the WaitHandle is
            ' signaled, stop future execution of the callback method
            ' by unregistering the WaitHandle.
            If Not ti.Handle Is Nothing Then
                ti.Handle.Unregister(Nothing)
            End If
        End If 

        Console.WriteLine("WaitProc( {0} ) executes on thread {1}; cause = {2}.", _
            ti.OtherInfo, _
            Thread.CurrentThread.GetHashCode().ToString(), _
            cause _
        )
    End Sub
End Class
using System;
using System.Threading;

// TaskInfo contains data that will be passed to the callback
// method.
public class TaskInfo {
    public RegisteredWaitHandle Handle = null;
    public string OtherInfo = "default";
}

public class Example {
    public static void Main(string[] args) {
        // The main thread uses AutoResetEvent to signal the
        // registered wait handle, which executes the callback
        // method.
        AutoResetEvent ev = new AutoResetEvent(false);

        TaskInfo ti = new TaskInfo();
        ti.OtherInfo = "First task";
        // The TaskInfo for the task includes the registered wait
        // handle returned by RegisterWaitForSingleObject.  This
        // allows the wait to be terminated when the object has
        // been signaled once (see WaitProc).
        ti.Handle = ThreadPool.RegisterWaitForSingleObject(
            ev,
            new WaitOrTimerCallback(WaitProc),
            ti,
            1000,
            false
        );

        // The main thread waits three seconds, to demonstrate the
        // time-outs on the queued thread, and then signals.
        Thread.Sleep(3100);
        Console.WriteLine("Main thread signals.");
        ev.Set();

        // The main thread sleeps, which should give the callback
        // method time to execute.  If you comment out this line, the
        // program usually ends before the ThreadPool thread can execute.
        Thread.Sleep(1000);
        // If you start a thread yourself, you can wait for it to end
        // by calling Thread.Join.  This option is not available with 
        // thread pool threads.
    }
   
    // The callback method executes when the registered wait times out,
    // or when the WaitHandle (in this case AutoResetEvent) is signaled.
    // WaitProc unregisters the WaitHandle the first time the event is 
    // signaled.
    public static void WaitProc(object state, bool timedOut) {
        // The state object must be cast to the correct type, because the
        // signature of the WaitOrTimerCallback delegate specifies type
        // Object.
        TaskInfo ti = (TaskInfo) state;

        string cause = "TIMED OUT";
        if (!timedOut) {
            cause = "SIGNALED";
            // If the callback method executes because the WaitHandle is
            // signaled, stop future execution of the callback method
            // by unregistering the WaitHandle.
            if (ti.Handle != null)
                ti.Handle.Unregister(null);
        } 

        Console.WriteLine("WaitProc( {0} ) executes on thread {1}; cause = {2}.",
            ti.OtherInfo, 
            Thread.CurrentThread.GetHashCode().ToString(), 
            cause
        );
    }
}

راجع أيضًا:

المرجع

ThreadPool

المبادئ

عمليات جزئية و مؤشر الترابط التشعبي

ملف الإدخال/الإخراج غير المتزامن

أجهزة ضبط الوقت

موارد أخرى

ترابط الكائنات و الميزات