Dispatcher.BeginInvoke: लैम्ब्डा को System.Delegate में नहीं बदल सकता


82

मैं फोन करने की कोशिश कर रहा हूं System.Windows.Threading.Dispatcher.BeginInvoke। विधि का हस्ताक्षर यह है:

BeginInvoke(Delegate method, params object[] args)

मैं इसे डेलिगेट बनाने के बजाय एक लैम्ब्डा पास करने की कोशिश कर रहा हूं।

_dispatcher.BeginInvoke((sender) => { DoSomething(); }, new object[] { this } );

यह मुझे एक संकलक त्रुटि कह रहा है कि मैं

मेमने को एक System.Delegate में नहीं बदल सकते।

प्रतिनिधि का हस्ताक्षर एक पैरामीटर के रूप में एक वस्तु लेता है और शून्य देता है। मेरा मेमना इससे मेल खाता है, फिर भी यह काम नहीं कर रहा है। मैं क्या खो रहा हूँ?

जवाबों:


71

चूंकि विधि एक System.Delegate लेता है , इसलिए आपको इसे एक विशिष्ट प्रकार का प्रतिनिधि देने की आवश्यकता है, जिसे इस तरह से घोषित किया गया है। यह एक प्रतिनिधि या नए प्रतिनिधिमंडल के माध्यम से निर्दिष्ट प्रतिनिधि के निर्माण के माध्यम से किया जा सकता है:

_dispatcher.BeginInvoke(
     new Action<MyClass>((sender) => { DoSomething(); }),
     new object[] { this } 
  );

इसके अलावा, जैसा कि SLaks बताते हैं, Dispatcher.BeginInvoke एक परमस एरे लेता है, ताकि आप इसे देख सकें:

_dispatcher.BeginInvoke(
     new Action<MyClass>((sender) => { DoSomething(); }),
     this
  );

या, यदि DoSomething इस ऑब्जेक्ट पर ही एक विधि है:

_dispatcher.BeginInvoke(new Action(this.DoSomething));

3
लेकिन (x) => {DoSomething () नहीं है; } प्रतिनिधि के हस्ताक्षर से मेल खाते हैं? मैंने सोचा कि मुझे यह सब बताना होगा।
मीका

@ मिचा: System.Delegate के पास कोई हस्ताक्षर नहीं है - यह सिर्फ "किसी भी प्रतिनिधि" पर है। आपको सिग के साथ एक प्रतिनिधि प्रकार प्रदान करना होगा। जो आपके उपयोग से मेल खाता है।
रीड कोपसी

@Reed लेकिन अगर MyMethod (Action Action) (और Action एक प्रतिनिधि है) के स्थान पर मैं MyMethod () () => {DoSomething ();}) को कॉल कर सकता हूं; मैं BeginInvoke के लिए एक ही काम क्यों नहीं कर सकता?
मीका

15
@ मिचा: वास्तव में प्रतिनिधि के लिए एक हस्ताक्षर नहीं है, जो कि इस मुद्दे का कारण बनता है। Invokeऔर BeginInvokeएक सामान्य Delegateवस्तु लें, जो किसी भी हस्ताक्षर की एक विधि का प्रतिनिधित्व कर सकती है। सामान्य परिस्थितियों में (जहां एक प्रतिनिधि विशेष हस्ताक्षर के लिए दृढ़ता से टाइप किया जाता है), संकलक विशिष्ट प्रतिनिधि प्रकार का अनुमान लगा सकता है। यही कारण है कि आप अन्य परिदृश्यों में प्रतिनिधि प्रकार को छोड़ने के साथ दूर जाने में सक्षम हैं। हालांकि, बाद से वहाँ है कोई वास्तविक प्रतिनिधि प्रकार यहाँ, संकलक एक उचित आधार (वास्तव में, यहां तक कि एक या, नहीं है का मतलब है ) एक प्रतिनिधि प्रकार का चयन करने का उपयोग करें।
एडम रॉबिन्सन

2
@ मिचाह: क्योंकि BeginInvoke को BeginInvoke (Action ..) के रूप में घोषित नहीं किया गया है, बल्कि BeginInvoke (System.Delegate, ..) यह किसी भी प्रतिनिधि प्रकार का उपयोग करने की अनुमति देता है, लेकिन आपको इसे स्पष्ट रूप से निर्दिष्ट करना होगा।
रीड कोपसी

73

कम:

_dispatcher.BeginInvoke((Action)(() => DoSomething()));

8
इससे भी छोटा: मुझे नहीं लगता कि आपको अभिव्यक्ति के आसपास ब्रेस {} और अर्धविराम की आवश्यकता है।
sp3ctum

3
आपको इसकी आवश्यकता भी नहीं है (), इसलिए यह हो सकता है_dispatcher.BeginInvoke((Action)(DoSomething));
mycroes

9

इनलाइन लैंबडा का उपयोग ...

Dispatcher.BeginInvoke((Action)(()=>{
  //Write Code Here
}));

7

यदि आप अपने प्रोजेक्ट से System.Windows.Presentation.dll को संदर्भित करते हैं और जोड़ते हैं, using System.Windows.Threadingतो आप एक एक्सटेंशन विधि का उपयोग कर सकते हैं जो आपको लैम्ब्डा सिंटैक्स का उपयोग करने की अनुमति देता है।

using System.Windows.Threading;

...

Dispatcher.BeginInvoke(() =>
{
});

मुझे यह काम करने के लिए नहीं मिल सकता है। क्या आप थोड़ा और विस्तार में जा सकते हैं?
टिम पोहल्मन

मैंने एक साधारण उदाहरण जोड़ा है। संदर्भ के लिए याद रखें System.Windows.Presentation.dll
Logicnet.dk

यह वास्तव में मैं क्या है, लेकिन अब यह काम करता है ... अजीब है। शायद मैंने पिछली बार कुछ गलत किया था।
टिम पोहल्मन

3

हम इसके लिए विस्तार विधियाँ बनाते हैं। उदाहरण के लिए

public static void BeginInvoke(this Control control, Action action)
    => control.BeginInvoke(action);

अब हम एक फार्म के भीतर से यह कॉल कर सकते हैं: this.BeginInvoke(() => { ... })

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.