كيفية القيام بما يلي: استخدم تجمع مؤشر ترابط (C# و Visual Basic)
تجمع مؤشر الترابط هو نموذج من متعدد العمليات في المهام التي يتم تمت الإضافة إلى قائمة الانتظار ويقوم تلقائياً بالبدء عندما يتم إنشاء عمليات جزئية. لمزيد من المعلومات، راجع تجمع مؤشر ترابط (C# و Visual Basic).
يستخدم المثال التالي تجمع مؤشرات الترابط .NET Framework لحساب النتيجة Fibonacciلعشرة أرقام بين 20 و 40. كل نتيجة Fibonacciتمثل بالفئة Fibonacci التي توفر أسلوباً يسمى ThreadPoolCallbackالتي تؤدي العملية الحسابية. الكائن الذي يمثل كل Fibonacci يتم إنشاء قيمة و الطريقة ThreadPoolCallback التي يتم تمريرها إلى QueueUserWorkItem ، الذي يقوم بتعيين مؤشرات الترابط المتوفرة في تجمع تنفيذ الأسلوب.
لأن كل كائن Fibonacci يتم إعطاءه قيمة شبه عشوائية للحساب ، ونظرًا لأن كل صواب سوف المنافسة لا تعرفه في وقت المعالج مقدماً كيفية طول مدة لنتائج عشرة كافة المطلوب حسابه. وهذا سبب كل كائن Fibonacci يتم تمرير مثيل فئة ManualResetEvent أثناء الإنشاء. كل كائن يشير إلى الحدث المتوفر عندما يكون حسابها كامل , مما يسمح مؤشر الترابط الرئيسي لحظر التنفيذ بواسطة WaitAll حتى يكون كل العشرة الكائنات Fibonacci قمت بحساب نتيجة. أسلوبMain ثم يعرض كل Fibonacci النتيجة .
مثال
Imports System.Threading
Module Module1
Public Class Fibonacci
Private _n As Integer
Private _fibOfN
Private _doneEvent As ManualResetEvent
Public ReadOnly Property N() As Integer
Get
Return _n
End Get
End Property
Public ReadOnly Property FibOfN() As Integer
Get
Return _fibOfN
End Get
End Property
Sub New(ByVal n As Integer, ByVal doneEvent As ManualResetEvent)
_n = n
_doneEvent = doneEvent
End Sub
' Wrapper method for use with the thread pool.
Public Sub ThreadPoolCallBack(ByVal threadContext As Object)
Dim threadIndex As Integer = CType(threadContext, Integer)
Console.WriteLine("thread {0} started...", threadIndex)
_fibOfN = Calculate(_n)
Console.WriteLine("thread {0} result calculated...", threadIndex)
_doneEvent.Set()
End Sub
Public Function Calculate(ByVal n As Integer) As Integer
If n <= 1 Then
Return n
End If
Return Calculate(n - 1) + Calculate(n - 2)
End Function
End Class
<MTAThread()>
Sub Main()
Const FibonacciCalculations As Integer = 9 ' 0 to 9
' One event is used for each Fibonacci object
Dim doneEvents(FibonacciCalculations) As ManualResetEvent
Dim fibArray(FibonacciCalculations) As Fibonacci
Dim r As New Random()
' Configure and start threads using ThreadPool.
Console.WriteLine("launching {0} tasks...", FibonacciCalculations)
For i As Integer = 0 To FibonacciCalculations
doneEvents(i) = New ManualResetEvent(False)
Dim f = New Fibonacci(r.Next(20, 40), doneEvents(i))
fibArray(i) = f
ThreadPool.QueueUserWorkItem(AddressOf f.ThreadPoolCallBack, i)
Next
' Wait for all threads in pool to calculate.
WaitHandle.WaitAll(doneEvents)
Console.WriteLine("All calculations are complete.")
' Display the results.
For i As Integer = 0 To FibonacciCalculations
Dim f As Fibonacci = fibArray(i)
Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN)
Next
End Sub
End Module
using System;
using System.Threading;
public class Fibonacci
{
private int _n;
private int _fibOfN;
private ManualResetEvent _doneEvent;
public int N { get { return _n; } }
public int FibOfN { get { return _fibOfN; } }
// Constructor.
public Fibonacci(int n, ManualResetEvent doneEvent)
{
_n = n;
_doneEvent = doneEvent;
}
// Wrapper method for use with thread pool.
public void ThreadPoolCallback(Object threadContext)
{
int threadIndex = (int)threadContext;
Console.WriteLine("thread {0} started...", threadIndex);
_fibOfN = Calculate(_n);
Console.WriteLine("thread {0} result calculated...", threadIndex);
_doneEvent.Set();
}
// Recursive method that calculates the Nth Fibonacci number.
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 = 10;
// One event is used for each Fibonacci object.
ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
Random r = new Random();
// Configure and start threads using ThreadPool.
Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
for (int i = 0; i < FibonacciCalculations; i++)
{
doneEvents[i] = new ManualResetEvent(false);
Fibonacci f = new Fibonacci(r.Next(20, 40), doneEvents[i]);
fibArray[i] = f;
ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
}
// Wait for all threads in pool to calculate.
WaitHandle.WaitAll(doneEvents);
Console.WriteLine("All calculations are complete.");
// Display the results.
for (int i= 0; i<FibonacciCalculations; i++)
{
Fibonacci f = fibArray[i];
Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
}
}
}
فيما يلي مثال للناتج.
launching 10 tasks...
thread 0 started...
thread 1 started...
thread 1 result calculated...
thread 2 started...
thread 2 result calculated...
thread 3 started...
thread 3 result calculated...
thread 4 started...
thread 0 result calculated...
thread 5 started...
thread 5 result calculated...
thread 6 started...
thread 4 result calculated...
thread 7 started...
thread 6 result calculated...
thread 8 started...
thread 8 result calculated...
thread 9 started...
thread 9 result calculated...
thread 7 result calculated...
All calculations are complete.
Fibonacci(38) = 39088169
Fibonacci(29) = 514229
Fibonacci(25) = 75025
Fibonacci(22) = 17711
Fibonacci(38) = 39088169
Fibonacci(29) = 514229
Fibonacci(29) = 514229
Fibonacci(38) = 39088169
Fibonacci(21) = 10946
Fibonacci(27) = 196418
راجع أيضًا:
المرجع
التأشير الترابطي ل Visual Basic و #Visual C
المبادئ
تجمع مؤشر ترابط (C# و Visual Basic)
موارد أخرى
كيفية: يزامن الوصول إلى مورد مشترك في بيئة متعدد العمليات بإستخدام #Visual C .NET