आपके प्रश्न के अनुसार ...
थ्रेड से ट्रेड.आर्टस्टार्ट () विधि को C # में कैसे पास करें?
... और आपके द्वारा की गई त्रुटि, आपको अपना कोड सही करना होगा
Thread thread = new Thread(new ThreadStart(download(filename));
सेवा
Thread thread = new Thread(new ThreadStart(download));
thread.Start(filename);
हालांकि, यह सवाल अधिक जटिल है क्योंकि यह पहले लगता है।
Thread
वर्ग वर्तमान में (4.7.2) कई प्रदान करता है कंस्ट्रक्टर्स और एक Start
भार के साथ विधि।
इस प्रश्न के लिए ये प्रासंगिक निर्माता हैं:
public Thread(ThreadStart start);
तथा
public Thread(ParameterizedThreadStart start);
जो या तो एक ThreadStart
प्रतिनिधि या एक ParameterizedThreadStart
प्रतिनिधि लेते हैं ।
संबंधित प्रतिनिधि इस तरह दिखते हैं:
public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);
जैसा कि देखा जा सकता है, उपयोग करने के लिए सही कंस्ट्रक्टर एक ParameterizedThreadStart
प्रतिनिधि लेने वाला प्रतीत होता है ताकि प्रतिनिधि द्वारा निर्दिष्ट हस्ताक्षर के अनुरूप कुछ विधि शुरू की जा सके।
Thread
वर्ग को अस्थिर करने के लिए एक सरल उदाहरण होगा
Thread thread = new Thread(new ParameterizedThreadStart(Work));
या केवल
Thread thread = new Thread(Work);
संबंधित विधि का हस्ताक्षर ( Work
इस उदाहरण में कहा जाता है) इस तरह दिखता है:
private void Work(object data)
{
...
}
जो कुछ बचा है वह धागा शुरू करना है। यह या तो उपयोग करके किया जाता है
public void Start();
या
public void Start(object parameter);
जबकि Start()
थ्रेड प्रारंभ होगा और null
विधि के डेटा के रूप में पास होगा, थ्रेड की विधि में कुछ भीStart(...)
पारित करने के लिए इस्तेमाल किया जा सकता है ।Work
हालांकि इस दृष्टिकोण के साथ एक बड़ी समस्या है: Work
विधि में पारित सब कुछ एक वस्तु में डाली जाती है। इसका मतलब है कि Work
विधि के भीतर इसे मूल प्रकार में फिर से डालना होगा जैसे कि निम्नलिखित उदाहरण में:
public static void Main(string[] args)
{
Thread thread = new Thread(Work);
thread.Start("I've got some text");
Console.ReadLine();
}
private static void Work(object data)
{
string message = (string)data; // Wow, this is ugly
Console.WriteLine($"I, the thread write: {message}");
}
कास्टिंग कुछ ऐसा है जो आप आमतौर पर नहीं करना चाहते हैं।
क्या होगा अगर कोई कुछ और गुजरता है जो एक स्ट्रिंग नहीं है? जैसा कि यह पहली बार में संभव नहीं लगता है (क्योंकि यह मेरी विधि है, मुझे पता है कि मैं क्या करता हूं या विधि निजी है, किसी को कभी भी इसे कैसे पारित करने में सक्षम होना चाहिए? ) संभवतः आप विभिन्न कारणों से वास्तव में उस मामले को समाप्त कर सकते हैं ? । जैसा कि कुछ मामलों में समस्या नहीं हो सकती है, अन्य हैं। ऐसे मामलों में आप शायद समाप्त हो जाएंगे, InvalidCastException
जिसे आप शायद नोटिस नहीं करेंगे क्योंकि यह केवल धागे को समाप्त करता है।
एक समाधान के रूप में आप एक सामान्य ParameterizedThreadStart
प्रतिनिधि प्राप्त करने की उम्मीद करेंगे जैसे ParameterizedThreadStart<T>
कि T
डेटा का प्रकार आप Work
विधि में पारित करना चाहते हैं । दुर्भाग्य से ऐसा कुछ मौजूद नहीं है (अभी तक?)।
हालाँकि इस समस्या का एक हल है। इसमें एक वर्ग बनाना शामिल है जिसमें दोनों शामिल हैं, थ्रेड को पास करने के लिए डेटा और साथ ही वह विधि जो इस तरह से कार्यकर्ता पद्धति का प्रतिनिधित्व करती है:
public class ThreadWithState
{
private string message;
public ThreadWithState(string message)
{
this.message = message;
}
public void Work()
{
Console.WriteLine($"I, the thread write: {this.message}");
}
}
इस दृष्टिकोण के साथ आप इस तरह धागा शुरू करेंगे:
ThreadWithState tws = new ThreadWithState("I've got some text");
Thread thread = new Thread(tws.Work);
thread.Start();
तो इस तरह से आप बस कास्टिंग करने से बचते हैं और एक थ्रेड को डेटा प्रदान करने का एक प्रकार है; ;;;