Nasıl yapılır: İş Parçacığı Yerel Değişkenleriyle bir Parallel.For Döngüsü Yazma
Bu örnekte, döngü For tarafından oluşturulan her ayrı görevde durum depolamak ve almak için iş parçacığı yerel değişkenlerinin nasıl kullanılacağı gösterilmektedir. İş parçacığı yerel verilerini kullanarak, paylaşılan duruma çok sayıda erişimi eşitleme yükünden kaçınabilirsiniz. Her yinelemede paylaşılan bir kaynağa yazmak yerine, görevin tüm yinelemeleri tamamlanana kadar değeri hesaplar ve depolarsınız. Ardından son sonucu paylaşılan kaynağa bir kez yazabilir veya başka bir yönteme geçirebilirsiniz.
Örnek
Aşağıdaki örnek, bir milyon öğe içeren bir dizideki değerlerin toplamını hesaplamak için yöntemini çağırır For<TLocal>(Int32, Int32, Func<TLocal>, Func<Int32,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) . Her öğenin değeri kendi dizinine eşittir.
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
class Test
{
static void Main()
{
int[] nums = Enumerable.Range(0, 1_000_000).ToArray();
long total = 0;
// Use type parameter to make subtotal a long, not an int
Parallel.For<long>(0, nums.Length, () => 0,
(j, loop, subtotal) =>
{
subtotal += nums[j];
return subtotal;
},
subtotal => Interlocked.Add(ref total, subtotal));
Console.WriteLine("The total is {0:N0}", total);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
'How to: Write a Parallel.For Loop That Has Thread-Local Variables
Imports System.Threading
Imports System.Threading.Tasks
Module ForWithThreadLocal
Sub Main()
Dim nums As Integer() = Enumerable.Range(0, 1000000).ToArray()
Dim total As Long = 0
' Use type parameter to make subtotal a Long type. Function will overflow otherwise.
Parallel.For(Of Long)(0, nums.Length, Function() 0, Function(j, [loop], subtotal)
subtotal += nums(j)
Return subtotal
End Function, Function(subtotal) Interlocked.Add(total, subtotal))
Console.WriteLine("The total is {0:N0}", total)
Console.WriteLine("Press any key to exit")
Console.ReadKey()
End Sub
End Module
Her For yöntemin ilk iki parametresi, başlangıç ve bitiş yineleme değerlerini belirtir. yönteminin bu aşırı yüklemesinde, üçüncü parametre yerel durumunuzu başlatabileceğiniz yerdir. Bu bağlamda yerel durum, yaşam süresi geçerli iş parçacığındaki döngünün ilk yinelemesinden hemen öncesinden son yinelemeden hemen sonrasına kadar uzanan bir değişken anlamına gelir.
Üçüncü parametrenin türü, Func<TResult> iş TResult
parçacığı yerel durumunu depolayacak değişkenin türüdür. Türü, genel yöntem çağrılırken sağlanan genel For<TLocal>(Int32, Int32, Func<TLocal>, Func<Int32,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) tür bağımsız değişkeni tarafından tanımlanır ve bu durumda olur Int64. tür bağımsız değişkeni derleyiciye iş parçacığı yerel durumunu depolamak için kullanılacak geçici değişkenin türünü bildirir. Bu örnekte, ifade () => 0
(veya Function() 0
Visual Basic'te) iş parçacığı yerel değişkenini sıfır olarak başlatır. Genel tür bağımsız değişkeni bir başvuru türü veya kullanıcı tanımlı değer türüyse, ifade şöyle görünür:
() => new MyClass()
Function() new MyClass()
Dördüncü parametre döngü mantığını tanımlar. İmzası C# veya Visual Basic'te olan Func<int, ParallelLoopState, long, long>
bir temsilci veya Func(Of Integer, ParallelLoopState, Long, Long)
lambda ifadesi olmalıdır. İlk parametre, döngünün bu yinelemesi için döngü sayacının değeridir. İkincisi, döngüden çıkmak için kullanılabilecek bir ParallelLoopState nesnedir; bu nesne sınıfı tarafından döngünün Parallel her oluşumuna sağlanır. Üçüncü parametre, iş parçacığı yerel değişkenidir. Son parametre dönüş türüdür. Bu durumda türün nedeni, tür bağımsız değişkeninde For belirttiğimiz tür olmasıdırInt64. Bu değişken adlandırılır subtotal
ve lambda ifadesi tarafından döndürülür. Dönüş değeri, döngünün sonraki her yinelemesinde başlatmak subtotal
için kullanılır. Bu son parametreyi, her yinelemeye geçirilen ve son yineleme tamamlandığında temsilciye localFinally
geçirilen bir değer olarak da düşünebilirsiniz.
Beşinci parametre, belirli bir iş parçacığındaki tüm yinelemeler tamamlandıktan sonra bir kez çağrılan yöntemi tanımlar. Giriş bağımsız değişkeninin türü yine yöntemin tür bağımsız değişkenine For<TLocal>(Int32, Int32, Func<TLocal>, Func<Int32,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) ve gövde lambda ifadesi tarafından döndürülen türe karşılık gelir. Bu örnekte değer, yöntemini çağırarak Interlocked.Add sınıf kapsamındaki bir değişkene iş parçacığı güvenli bir şekilde eklenir. İş parçacığı yerel değişkenini kullanarak döngünün her yinelemesinde bu sınıf değişkenine yazmaktan kaçındık.
Lambda ifadelerini kullanma hakkında daha fazla bilgi için bkz . PLINQ ve TPL'de Lambda İfadeleri.
Ayrıca bkz.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin