2010-02-06 14 views
31

में कॉल किया गया है, मेरे पास यह छोटी विधि है जिसे थ्रेड सुरक्षित माना जाता है। सबकुछ तब तक काम करता है जब तक कि मैं शून्य के बजाए वापसी मूल्य नहीं चाहता। BeginInvoke कहलाता है जब मैं वापसी मूल्य कैसे प्राप्त करूं?वापसी मूल्य कैसे प्राप्त करें जब BeginInvoke/Invoke को C#

public static string readControlText(Control varControl) { 
     if (varControl.InvokeRequired) { 
      varControl.BeginInvoke(new MethodInvoker(() => readControlText(varControl))); 
     } else { 
      string varText = varControl.Text; 
      return varText; 
     } 

    } 

संपादित करें: मैं होने लगता है BeginInvoke इस मामले मैं जीयूआई से मूल्य की जरूरत के रूप में धागा जारी रखने से पहले में nessecary नहीं है। तो Invoke का उपयोग भी अच्छा है। मूल्य वापस करने के लिए उदाहरण के उदाहरण में इसका उपयोग करने के लिए कोई संकेत नहीं है।

private delegate string ControlTextRead(Control varControl); 
    public static string readControlText(Control varControl) { 
     if (varControl.InvokeRequired) { 
      varControl.Invoke(new ControlTextRead(readControlText), new object[] {varControl}); 
     } else { 
      string varText = varControl.Text; 
      return varText; 
     } 

    } 

लेकिन यकीन है कि कैसे मान जो कोड का उपयोग कर या तो पाने के लिए;)

+0

यदि आपको किसी आमंत्रण से लौटाए गए मूल्य के साथ काम करने की आवश्यकता है, तो ऐसा होना चाहिए क्योंकि आपको "निरंतरता उत्तीर्ण शैली" पैटर्न की आवश्यकता है। जिसे 'async',' await' और 'कार्य' के साथ कम किया जा सकता है। –

उत्तर

49

आपको आमंत्रित करना होगा() ताकि आप फ़ंक्शन को वापस लौटने और इसके वापसी मूल्य प्राप्त करने का इंतजार कर सकें। आपको एक और प्रतिनिधि प्रकार की भी आवश्यकता होगी। यह काम करना चाहिए:

public static string readControlText(Control varControl) { 
    if (varControl.InvokeRequired) { 
    return (string)varControl.Invoke(
     new Func<String>(() => readControlText(varControl)) 
    ); 
    } 
    else { 
    string varText = varControl.Text; 
    return varText; 
    } 
} 
1

क्या आप विधि से एक वापसी मान चाहते हैं, आप विधि के async संस्करण का उपयोग नहीं किया जाना चाहिए, आप .Invoke(...) का उपयोग करना चाहिए । जो तुल्यकालिक है, यह है कि यह आपके प्रतिनिधि को निष्पादित करेगा, और यह पूरा होने तक वापस नहीं आएगा। आपके उदाहरण में अब यह है, BeginInvoke आपके प्रतिनिधि को निष्पादित करने का अनुरोध भेजेगा, और तुरंत वापस लौटाएगा। तो वापस लौटने के लिए कुछ भी नहीं है।

+0

जब तक मैं वापस मूल्य प्राप्त करता हूं तब तक इसे आमंत्रित या आरंभ करें। मुझे केवल अन्य धागे से combobox या टेक्स्टबॉक्स के मूल्य को पढ़ने की जरूरत है। – MadBoy

1

ऐसा कुछ है जो आप चाहते थे?

// begin execution asynchronously 
IAsyncResult result = myObject.BeginInvoke("data.dat", null, null); 

// wait for it to complete 
while (result.IsCompleted == false) { 
    // do some work 
    Thread.Sleep(10); 
    } 

// get the return value 
int returnValue = myObject.EndInvoke(result); 
+0

काफी नहीं। मुझे लगता है कि BeginInvoke का उपयोग nessecary नहीं है क्योंकि मैं सिर्फ कॉम्बोबॉक्स या टेक्स्टबॉक्स का मान पढ़ना चाहता हूं और यह मान अन्य आदेशों को निष्पादित करने के लिए महत्वपूर्ण है। तो मैं इसे Invoke में उपयोग कर सकता था। बस यह सुनिश्चित न करें कि मैं अपने मामले में अपने उदाहरण का उपयोग कैसे कर सकता हूं, इसका मुख्य उद्देश्य किसी अन्य थ्रेड से विधि को कॉल करना है, गुई वैल्यू पढ़ना और मुझे वापस लेना ताकि प्रोग्राम आगे जा सके। – MadBoy

3
public static string readControlText(Control varControl) 
{ 
    if (varControl.InvokeRequired) 
    { 
     string res = ""; 
     var action = new Action<Control>(c => res = c.Text); 
     varControl.Invoke(action, varControl); 
     return res; 
    } 
    string varText = varControl.Text; 
    return varText; 
} 
+0

nobugz समाधान के समान दिखता है लेकिन वह मेरे लिए क्लीनर दिखता है :-) – MadBoy

+0

हाँ, मैं सहमत हूं। जब मैंने अपना समाधान पोस्ट किया, तो मुझे अभी तक nobugz समाधान नहीं दिख रहा है :) –

16

EndInvoke एक BeginInvoke कॉल से एक वापसी मान प्राप्त करने के लिए इस्तेमाल किया जा सकता है। उदाहरण के लिए:

public static void Main() 
    { 
     // The asynchronous method puts the thread id here. 
     int threadId; 

     // Create an instance of the test class. 
     AsyncDemo ad = new AsyncDemo(); 

     // Create the delegate. 
     AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod); 

     // Initiate the asychronous call. 
     IAsyncResult result = caller.BeginInvoke(3000, 
      out threadId, null, null); 

     Thread.Sleep(0); 
     Console.WriteLine("Main thread {0} does some work.", 
      Thread.CurrentThread.ManagedThreadId); 

     // Call EndInvoke to wait for the asynchronous call to complete, 
     // and to retrieve the results. 
     string returnValue = caller.EndInvoke(out threadId, result); 

     Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", 
      threadId, returnValue); 
    } 
} 
+0

कुल मिलाकर अच्छा उदाहरण, हालांकि मेरे मामले में nobugz समाधान सही है और वास्तव में क्या आवश्यक था। – MadBoy

0
delegate string StringInvoker(); 
    string GetControlText() 
    { 
     if (control.InvokeRequired) 
     { 
      string controltext = (string)control.Invoke(new StringInvoker(GetControlText)); 
      return(controltext); 
     } 
     else 
     { 
      return(control.Text); 
     } 
    } 

// सरल & सुरुचिपूर्ण लेकिन यह एक और धागा प्रतिनिधि निष्पादित करने के लिए के लिए प्रतीक्षा करने की जरूरत है; हालांकि यदि आप परिणामों के बिना आगे बढ़ नहीं सकते हैं ...

संबंधित मुद्दे