2010-04-15 6 views
5

मैं aruguments साथ थ्रेड में विधि कॉल और यहाँ कुछ मूल्य उदाहरणकैसे aruguments साथ थ्रेड में विधि कॉल और कुछ मान देने के लिए

class Program 
    { 
     static void Main() 
     { 
      Thread FirstThread = new Thread(new ThreadStart(Fun1)); 
      Thread SecondThread = new Thread(new ThreadStart(Fun2)); 
      FirstThread.Start(); 
      SecondThread.Start();   


     } 
     public static void Fun1() 
     { 
      for (int i = 1; i <= 1000; i++) 
      { 
       Console.WriteLine("Fun1 writes:{0}", i); 
      } 
     } 
     public static void Fun2() 
     { 
      for (int i = 1000; i >= 6; i--) 
      { 
       Console.WriteLine("Fun2 writes:{0}", i); 
      } 
     } 

    } 

मुझे पता है यह ऊपर के उदाहरण सफलतापूर्वक चला लौट लेकिन अगर चाहते विधि fun1 इस तरह

public int fun1(int i,int j) 
{ 
    int k; 
    k=i+j; 
    return k; 
} 

तो मैं इसे थ्रेड में कैसे कॉल कर सकता हूं। यह संभव .Any शरीर सहायता है me..i हर संभव तरीके की जरूरत के लिए यह

+0

मुझे लगता है कि ये उदाहरण पर्याप्त हैं। यदि यह उत्तर आपकी अपेक्षा से मेल नहीं खाता है, तो पूरा परिदृश्य दें और आपको क्या चाहिए। – Mohanavel

उत्तर

6

यह एक और दृष्टिकोण हो सकता है। यहां इनपुट पैरामीटरकृत थ्रेड के रूप में पारित किया गया है और प्रतिनिधि प्रकार प्रतिनिधि कार्यक्रम में पारित किया जाता है, ताकि जब धागा पूरा हो जाए तो वह प्रतिनिधि को कॉल करेगा। थ्रेड पूरा होने पर परिणाम प्राप्त करना ठीक होगा।

public class ThreadObject 
    { 
     public int i; 
     public int j; 
     public int result; 
     public string Name; 
    } 



    public delegate void ResultDelegate(ThreadObject threadObject); 

    public partial class Form1 : Form 
    { 

     public event ResultDelegate resultDelete; 

     public Form1() 
     { 
      InitializeComponent(); 

      resultDelete += new ResultDelegate(resultValue); 
     } 

     void resultValue(ThreadObject threadObject) 
     { 
      MessageBox.Show("Thread Name : " + threadObject.Name + " Thread Value : " + threadObject.result); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      ThreadObject firstThreadObject = new ThreadObject(); 
      firstThreadObject.i = 0; 
      firstThreadObject.j = 100; 
      firstThreadObject.Name = "First Thread"; 

      Thread firstThread = new Thread(Fun); 
      firstThread.Start(firstThreadObject); 


      ThreadObject secondThreadObject = new ThreadObject(); 
      secondThreadObject.i = 0; 
      secondThreadObject.j = 200; 
      secondThreadObject.Name = "Second Thread"; 

      Thread secondThread = new Thread(Fun); 
      secondThread.Start(secondThreadObject); 

     } 


     private void Fun(object parameter) 
     { 
      ThreadObject threadObject = parameter as ThreadObject; 

      for (; threadObject.i < threadObject.j; threadObject.i++) 
      { 
       threadObject.result += threadObject.i; 

       Thread.Sleep(10); 
      } 

      resultValue(threadObject); 
     } 
    } 
24

आपको गुमनाम विधि या लैम्ब्डा उपयोग करने के लिए पूर्ण स्थिर जाँच प्रदान करने के लिए सक्षम होना चाहिए:

Thread FirstThread = new Thread(() => Fun1(5, 12)); 

या यदि आप चाहते हैं परिणाम के साथ कुछ करना:

Thread FirstThread = new Thread(() => { 
    int i = Fun1(5, 12); 
    // do something with i 
}); 

लेकिन ध्यान दें कि यह "पर कब्जा कर लिया चर का अभी भी नया थ्रेड के संदर्भ में चलाता है" कुछ करना "(लेकिन बाहरी विधि में अन्य चर के उपयोग के साथ (Main) शिष्टाचार ")।

आप सी # 2.0 (और नहीं ऊपर) है, तो:

Thread FirstThread = new Thread((ThreadStart)delegate { Fun1(5, 12); }); 

और

Thread FirstThread = new Thread((ThreadStart)delegate { 
    int i = Fun1(5, 12); 
    // do something with i 
}); 
+0

यदि कोई अन्य विधियां उपलब्ध हैं तो आपको धन्यवाद ... – ratty

+0

@ratty - आपको वास्तव में क्या पसंद आएगा? –

0

आप धागा निर्माता पर ParameterizedThreadStart अधिभार उपयोग कर सकते हैं। यह आपको अपनी थ्रेड विधि के पैरामीटर के रूप में ऑब्जेक्ट पास करने की अनुमति देता है। यह एक ऑब्जेक्ट पैरामीटर होने जा रहा है, इसलिए मैं आमतौर पर ऐसे धागे के लिए पैरामीटर क्लास बना देता हूं .. यह ऑब्जेक्ट थ्रेड निष्पादन के परिणाम को भी संग्रहीत कर सकता है, जिसे आप थ्रेड समाप्त होने के बाद पढ़ सकते हैं।

भूलें कि धागे चलने के दौरान इस ऑब्जेक्ट को एक्सेस करना संभव नहीं है, लेकिन "थ्रेड सुरक्षित" नहीं है। आप ड्रिल :)

यहाँ एक उदाहरण है पता:

void Main() 
{ 
    var thread = new Thread(Fun); 
    var obj = new ThreadObject 
    { 
     i = 1, 
     j = 15, 
    }; 

    thread.Start(obj); 
    thread.Join(); 
    Console.WriteLine(obj.result); 
} 

public static void Fun(Object obj) 
{ 
    var threadObj = obj as ThreadObject; 
    threadObj.result = threadObj.i + threadObj.j; 
} 

public class ThreadObject 
{ 
    public int i; 
    public int j; 
    public int result; 
} 
0

कुछ विकल्प के लिए; currying:

static ThreadStart CurryForFun(int i, int j) 
{ // also needs a target object if Fun1 not static 
    return() => Fun1(i, j); 
} 

Thread FirstThread = new Thread(CurryForFun(5, 12)); 

या अपना स्वयं का कब्जा प्रकार बारे में (यह मोटे तौर पर जब आप शीघ्र-तरीकों/पर कब्जा कर लिया चर के साथ lambdas का उपयोग क्या संकलक आप के लिए करता है के बराबर है, लेकिन अलग ढंग से लागू किया गया है):

class MyCaptureClass 
{ 
    private readonly int i, j; 
    int? result; 
    // only available after execution 
    public int Result { get { return result.Value; } } 
    public MyCaptureClass(int i, int j) 
    { 
     this.i = i; 
     this.j = j; 
    } 
    public void Invoke() 
    { // will also need a target object if Fun1 isn't static 
     result = Fun1(i, j); 
    } 
} 
... 
MyCaptureClass capture = new MyCaptureClass(5, 12); 
Thread FirstThread = new Thread(capture.Invoke); 
// then in the future, access capture.Result 
1

बहुत सरल तरीका अलग थ्रेड में समारोह निष्पादित करने के लिए नहीं है:

// Create function delegate (it can be any delegate) 
var FunFunc = new Func<int, int, int>(fun1); 
// Start executing function on thread pool with parameters 
IAsyncResult FunFuncResult = FunFunc.BeginInvoke(1, 5, null, null); 
// Do some stuff 
// Wait for asynchronous call completion and get result 
int Result = FunFunc.EndInvoke(FunFuncResult); 

इस समारोह थ्रेड पूल धागे पर निष्पादित किया जाएगा, और कहा कि तर्क पूरी तरह से आपके आवेदन के लिए पारदर्शी है। सामान्य रूप से, मैं समर्पित थ्रेड के बजाय थ्रेड पूल पर ऐसे छोटे कार्यों को निष्पादित करने का सुझाव देता हूं।

7

मुझे मार्क ग्रेवल का जवाब पसंद है। आप अपने परिणाम को मुख्य थ्रेड पर वापस थोड़ा सा संशोधन के साथ पास कर सकते हैं:

int fun1, fun2; 
Thread FirstThread = new Thread(() => { 
    fun1 = Fun1(5, 12); 
}); 
Thread SecondThread = new Thread(() => { 
    fun2 = Fun2(2, 3); 
}); 

FirstThread.Start(); 
SecondThread.Start(); 
FirstThread.Join(); 
SecondThread.Join(); 

Console.WriteLine("Fun1 returned {0}, Fun2 returned {1}", fun1, fun2); 
संबंधित मुद्दे