[ThreadStatic]
ThreadLocal<T>
जेनेरिक का उपयोग करते समय विशेषता का उपयोग कर परिभाषित किया गया है । अलग-अलग डिज़ाइन समाधान क्यों चुना गया? इस मामले में जेनेरिक विशेषताओं का उपयोग करने के क्या फायदे और नुकसान हैं?
[ThreadStatic]
ThreadLocal<T>
जेनेरिक का उपयोग करते समय विशेषता का उपयोग कर परिभाषित किया गया है । अलग-अलग डिज़ाइन समाधान क्यों चुना गया? इस मामले में जेनेरिक विशेषताओं का उपयोग करने के क्या फायदे और नुकसान हैं?
जवाबों:
टिप्पणियों में नोट किया गया कुछ ब्लॉग पोस्ट स्पष्ट नहीं करता है, लेकिन मुझे बहुत महत्वपूर्ण लगता है, यह है कि [ThreadStatic]
हर थ्रेड के लिए चीजों को स्वचालित रूप से प्रारंभ नहीं करता है। उदाहरण के लिए, मान लें कि आपके पास यह है:
[ThreadStatic]
private static int Foo = 42;
इसका उपयोग करने वाला पहला धागा Foo
आरंभिक रूप से दिखाई देगा 42
। लेकिन बाद के धागे नहीं होंगे। इनिलाइज़र केवल पहले थ्रेड के लिए काम करता है। तो आप अंत में यह जांचने के लिए कोड लिखना चाहते हैं कि क्या यह आरंभिक है।
ThreadLocal<T>
उस समस्या को हल करता है जिससे आप आरंभीकरण फ़ंक्शन (रीड के ब्लॉग शो के रूप में) की आपूर्ति कर सकते हैं जो पहली बार आइटम के एक्सेस होने से पहले चलता है।
मेरी राय में, [ThreadStatic]
इसके बजाय का उपयोग करने के लिए कोई फायदा नहीं है ThreadLocal<T>
।
ThreadLocal<T>
नेट 4 और में उपलब्ध है, और विशेषता भी 3.5 और नीचे में उपलब्ध है। ThreadStatic
ThreadLocal<T>
लागू करने IDisposable
और आमतौर पर आपको लागू IDisposable
करने के लिए मजबूर करता है, जो आपके कॉल करने वालों को आपको निपटाने के लिए मजबूर करता है और इसलिए भी लागू होता है IDisposable
...
ThreadLocal
या उसके ThreadStatic
साथ बहुत सावधान रहूंगा । वे मूल्य पूल धागे के पूरे जीवन के माध्यम से रहेंगे, न कि केवल उस कार्य के लिए जो आप इसे असाइन करते हैं। जो आपको कुछ स्पष्ट गैर-स्पष्ट तरीकों से परेशान कर सकता है। अधिक जानकारी के लिए stackoverflow.com/questions/561518/… और इसी तरह के प्रश्न देखें ।
static
? देखें msdn.microsoft.com/en-us/library/...
थ्रेडस्टैटिक इनिशियलाइज़ केवल पहले थ्रेड पर, थ्रेडलोकल इनिशियलाइज़ प्रत्येक थ्रेड के लिए। नीचे सरल प्रदर्शन है:
public static ThreadLocal<int> _threadlocal =
new ThreadLocal<int>(() =>
{
return Thread.CurrentThread.ManagedThreadId;
});
public static void Main()
{
new Thread(() =>
{
for (int x = 0; x < _threadlocal.Value; x++)
{
Console.WriteLine("First Thread: {0}", x);
}
}).Start();
new Thread(() =>
{
for (int x = 0; x < _threadlocal.Value; x++)
{
Console.WriteLine("Second Thread: {0}", x);
}
}).Start();
Console.ReadKey();
}
थ्रेडस्टैटिक के पीछे मुख्य विचार प्रत्येक थ्रेड के लिए चर की एक अलग प्रतिलिपि बनाए रखना है ।
class Program
{
[ThreadStatic]
static int value = 10;
static void Main(string[] args)
{
value = 25;
Task t1 = Task.Run(() =>
{
value++;
Console.WriteLine("T1: " + value);
});
Task t2 = Task.Run(() =>
{
value++;
Console.WriteLine("T2: " + value);
});
Task t3 = Task.Run(() =>
{
value++;
Console.WriteLine("T3: " + value);
});
Console.WriteLine("Main Thread : " + value);
Task.WaitAll(t1, t2, t3);
Console.ReadKey();
}
}
उपरोक्त स्निपेट में, हमारे पास value
प्रत्येक धागे के लिए एक अलग कॉपी है , जिसमें मुख्य धागा भी शामिल है।
तो, एक थ्रेडस्टैटिक वैरिएबल को थ्रेड को छोड़कर अन्य थ्रेड्स पर इसके डिफ़ॉल्ट मान पर आरम्भ किया जाएगा, जिस पर इसे बनाया गया है।
यदि हम अपने तरीके से प्रत्येक थ्रेड पर वैरिएबल को इनिशियलाइज़ करना चाहते हैं, तो थ्रेडलोकल का उपयोग करें।