10

Kayıt noktası bilgilerini TLS'de saklamak istiyorum, böylece giriş noktasında bir değer ayarlayabilir ve bu değer tüm sonuç yığınlarında kullanılabilir. Bu iyi çalışır, ancak TPL ve ThreadPool'u da kullanırım. Sorun daha sonra TLS verilerini diğer iş parçacıklarına geçirme haline gelir. Hepsini kendim yapabilirim ama sonra Parallel.For gibi güzel yöntemleri kaybederim.TPL kullanırken Thread Local Storage (TLS) nasıl yönetilir?

TLS'yi TPL kullanırken kopyalamanın bir yolu var mı? Bu, bekleme özelliğini aldığında C# için de geçerli olacaktır.

sayesinde Erick

cevap

5

Genellikle bu zaten parçacığı yerel veri sağlayan Parallel.For bir aşırı kullanarak aracılığıyla ele alınır.

Bu aşırı yükleme, iş parçacığı yerel verileriniz için iş parçacığı başına etkili bir başlatma ve sonuçta birlikte "birleştirmek" için sonuçta bir birleştirme işlevi olan bir başlatma ve bir sonlandırma temsilci sağlamanıza olanak sağlar (bu, bir kez çalıştırılır) iplik). I wrote about this in detail here.

object sync = new object(); 
double result = 0; 

Parallel.For(0, collection.Count, 
    // Initialize thread local data: 
    () => new MyThreadSpecificData(), 
    // Process each item 
    (i, pls, currentThreadLocalData) => 
    { 
     // Generate a NEW version of your local state data 
     MyThreadSpecificData newResults = ProcessItem(collection, i, currentThreadLocalData); 
     return newResults; 
    }, 
    // Aggregate results 
    threadLocalData => 
    { 
     // This requires synchronization, as it happens once per thread, 
     // but potentially simultaneously 
     lock(sync) 
      result += threadLocalData.Results; 
    }); 
+0

Teşekkürler Reed - istediğimi yapıyor, ancak sorunu çözmek için farklı bir yol buldum. Yine de, bu yakında kullanacağım mükemmel bir şey. –

+0

Neden böyle çirkin bir aşırı yük dahil ettiklerini merak ediyorum? Bu oranda, yalnızca iş parçacığı verilerini başlatacak ve ana delegenizde baştan başlatmak için daha temiz olacaktır. Mükemmel optimize edilmedikçe ...? –

+0

@ TimLovell-Smith İş parçacığı yerel verileri birden fazla delege çağrısında yeniden kullanılır, bu nedenle tek bir delege içinde başlatılamaz/sonlandırılamaz. (İşte buradaki nokta;)) –

4

ben kod gerektirmez sorununa başka bir çözüm bulundu:

temel formu gibi bir şey yapmaktır. Verileri bir "mantıksal iş parçacığına" eklemek için CallContext'i kullanabildim. Bu veriler başlangıç ​​ipliğinden TPL ve ThreadPool tarafından üretilen dişlere aktarılır.

http://www.wintellect.com/CS/blogs/jeffreyr/archive/2010/09/27/logical-call-context-flowing-data-across-threads-appdomains-and-processes.aspx

+5

Sadece FYI - Bu mekanizma, her bir içerik çağrısı aracılığıyla veriyi serileştirirken, TLS'yi kullanmaktan çok daha yavaştır ... –

0

Orada, tabii ki, henüz başka bir alternatif: yaptığımız gibi bir TaskLocal (T) sınıfı yaz, bu oldukça geçerli Konu daha güncel Görev üzerindeki depolama dayandırır. Açıkçası, Microsoft'un bunu neden ilk Görev uygulamasının bir parçası olarak yapmadığı konusunda hiçbir fikrim yok.

Önemli Uygulama not: beklemektedir çağıran Görev kodu farklı GörevKimliği olarak bölünmüş ve devam edilebilir olduğundan, ayrıca biz de yaptığını yapmak ve yeni TaskIds eşler TaskLocal (T) bir yöntemi uygulamak gerekir öncekilere, daha sonra Görev başlangıcında asıl TaskId'ı kaydedin ve her bekletme çağrısından sonra eşleyin.

+0

Bunu gösteren bir kod örneği, +1'i benden alır :-) – JoshBerke

+0

Ne yapabileceğimi göreceğim ... (: – Thought

+0

Bu harika olurdu! – JoshBerke