2008-10-31 14 views
113

सिंटैक्स के साथ कुछ परेशानी होने के बाद, जहां हम एक प्रतिनिधि के रूप में अज्ञात रूप से एक प्रतिनिधि को कॉल करना चाहते हैं। इन्वोक।कॉल को आमंत्रित करने में बेनामी विधि

हमने कई अलग-अलग दृष्टिकोणों की कोशिश की है, सभी का कोई फायदा नहीं हुआ।

उदाहरण के लिए:

myControl.Invoke(delegate() { MyMethod(this, new MyEventArgs(someParameter)); }); 

जहां someParameter इस विधि

लिए स्थानीय है ऊपर एक संकलक त्रुटि में परिणाम होगा:

Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type

उत्तर

200

क्योंकि Invoke/BeginInvokeDelegate (बजाय एक टाइप किया प्रतिनिधि से) स्वीकार करने पर आपको संकलक बनाने के लिए प्रतिनिधि किस प्रकार बताने के लिए की जरूरत है; MethodInvoker (2.0) या Action (3.5) आम विकल्प हैं (ध्यान दें कि उनके पास एक ही हस्ताक्षर है); जैसे इतना:

string message = "Hi"; 
control.Invoke((MethodInvoker) delegate {this.Text = message;}); 

(चेतावनी:

control.Invoke((MethodInvoker) delegate {this.Text = "Hi";}); 

आप मानकों में पारित करने के लिए की जरूरत है, फिर "पर कब्जा कर लिया चर" जिस तरह से कर रहे हैं आप अगर कैप्चर का उपयोग कर async थोड़ा सावधान रहना चाहिए , लेकिन सिंक ठीक है - यानी ऊपर ठीक है)

एक अन्य विकल्प एक विस्तार विधि लिखने के लिए है:

public static void Invoke(this Control control, Action action) 
{ 
    control.Invoke((Delegate)action); 
} 
तो

:

this.Invoke(delegate { this.Text = "hi"; }); 
// or since we are using C# 3.0 
this.Invoke(() => { this.Text = "hi"; }); 

आप निश्चित रूप से BeginInvoke साथ भी ऐसा ही कर सकते हैं:

public static void BeginInvoke(this Control control, Action action) 
{ 
    control.BeginInvoke((Delegate)action); 
} 

आप सी # 3.0 उपयोग नहीं कर सकते हैं, तो आप एक नियमित रूप से उदाहरण विधि के साथ भी ऐसा ही कर सकता है , संभवतः Form बेस-क्लास में।

+0

कैसे कर सकते हैं करने के लिए सही जवाब होना चाहिए मैं इस जवाब में अपने पहले समाधान के लिए पैरामीटर पास? मेरा मतलब यह समाधान था: control.Invoke ((MethodInvoker) प्रतिनिधि {this.Text = "हाय";}); – uzay95

+1

ऐक्शन में स्पष्ट भूमिका निभाने के बिना एक्सटेंशन विधि क्यों लागू की जाती है? –

+0

क्योंकि संकलक उपयोग से अनुमान लगा सकता है। – RoboJ1M

13
myControl.Invoke(new MethodInvoker(delegate() {...})) 
13

आप एक प्रतिनिधि बनाने की जरूरत प्रकार। अज्ञात विधि निर्माण में कीवर्ड 'प्रतिनिधि' थोड़ा भ्रामक है। आप एक अज्ञात प्रतिनिधि नहीं बना रहे हैं लेकिन एक अनाम विधि है। आपके द्वारा बनाई गई विधि का उपयोग प्रतिनिधिमंडल में किया जा सकता है। इस तरह:

myControl.Invoke(new MethodInvoker(delegate() { (MyMethod(this, new MyEventArgs(someParameter)); })); 
+0

मुझे लगता है कि यह इस सवाल – electricalbah

42

असल में आपको प्रतिनिधि कीवर्ड का उपयोग करने की आवश्यकता नहीं है। बस पैरामीटर के रूप में लैम्ब्डा पारित:

control.Invoke((MethodInvoker)(() => {this.Text = "Hi"; })); 
5

मैं अन्य सुझावों के साथ समस्या नहीं थी क्योंकि मैं कभी कभी अपने तरीकों से मूल्यों को वापस जाने के लिए चाहते हैं। यदि आप रिटर्न वैल्यू के साथ MethodInvoker का उपयोग करने का प्रयास करते हैं तो ऐसा लगता है कि यह पसंद नहीं है। तो मैं जिस समाधान का उपयोग करता हूं वह इस तरह है (इसे और अधिक संक्षिप्त बनाने के लिए एक तरीका सुनकर बहुत खुश - मैं C# .net 2 का उपयोग कर रहा हूं।0):

// Create delegates for the different return types needed. 
    private delegate void VoidDelegate(); 
    private delegate Boolean ReturnBooleanDelegate(); 
    private delegate Hashtable ReturnHashtableDelegate(); 

    // Now use the delegates and the delegate() keyword to create 
    // an anonymous method as required 

    // Here a case where there's no value returned: 
    public void SetTitle(string title) 
    { 
     myWindow.Invoke(new VoidDelegate(delegate() 
     { 
      myWindow.Text = title; 
     })); 
    } 

    // Here's an example of a value being returned 
    public Hashtable CurrentlyLoadedDocs() 
    { 
     return (Hashtable)myWindow.Invoke(new ReturnHashtableDelegate(delegate() 
     { 
      return myWindow.CurrentlyLoadedDocs; 
     })); 
    } 
7

पूर्णता के लिए के लिए, यह भी एक कार्य विधि/गुमनाम विधि संयोजन के माध्यम से पूरा किया जा सकता:

//Process is a method, invoked as a method group 
Dispatcher.Current.BeginInvoke((Action) Process); 
//or use an anonymous method 
Dispatcher.Current.BeginInvoke((Action)delegate => { 
    SomeFunc(); 
    SomeOtherFunc(); 
}); 
संबंधित मुद्दे