2009-08-06 8 views
13

कोड के नीचे दिखाई देता है:जब किसी ईवेंट में एकाधिक ग्राहक होते हैं, तो मैं प्रत्येक ग्राहक के लिए वापसी मूल्य कैसे प्राप्त करूं?

घड़ी:

public class Clock 
{ 
    public event Func<DateTime, bool> SecondChange; 

    public void Run() 
    { 
     for (var i = 0; i < 20; i++) 
     { 
      Thread.Sleep(1000); 

      if (SecondChange != null) 
      { 
       //how do I get return value for each subscriber? 
       Console.WriteLine(SecondChange(DateTime.Now)); 
      } 
     } 
    } 
} 

DisplayClock:

public class DisplayClock 
{ 
    public static bool TimeHasChanged(DateTime now) 
    { 
     Console.WriteLine(now.ToShortTimeString() + " Display"); 
     return true; 
    } 
} 

LogClock:

:

public class LogClock 
{ 
    public static bool WriteLogEntry(DateTime now) 
    { 
     Console.WriteLine(now.ToShortTimeString() + " Log"); 
     return false; 
    } 
} 

कोड को चलाने के लिए

अन्य प्रश्न हैं:

  • यह एक मूल्य के वापस जाने के लिए प्रत्येक ग्राहक के लिए अच्छा अभ्यास है?
  • यह अच्छा सिर्फ घटना वापसी प्रकार के बजाय मैन्युअल रूप से एक प्रतिनिधि के रूप में घोषित करने की घोषणा करने के लड़ाई/समारोह अभ्यास है?

उत्तर

26

उपयोग Delegate.GetInvocationList

if (SecondChange != null) 
{ 
    DateTime now = DateTime.Now; 
    foreach (Delegate d in SecondChange.GetInvocationList()) 
    { 
     Console.WriteLine(d.DynamicInvoke(now)); 
    } 
} 

यह अच्छा अभ्यास सिर्फ लड़ाई/समारोह का उपयोग करने के बजाय स्वयं एक प्रतिनिधि की घोषणा है?

हां। लेकिन मैं बताउंगा कि सर्वोत्तम अभ्यास Func<..., TResult> के बजाय EventHandler<T> का उपयोग करने के लिए है। EventHandler<T> रिटर्न वैल्यू का समर्थन नहीं करता है, लेकिन आप कुछ हद तक उचित हैं कि कुछ .NET ईवेंट हैं जिनके पास मूल्य वापस आते हैं। मैं एक कस्टम EventArgs उपवर्ग है कि आप अपने T के रूप में उपयोग में एक settable संपत्ति के लिए यह बेहतर विचार करेंगे। यह वह पैटर्न है जिसे हम KeyEventArgs.Handled जैसी चीज़ों में देखते हैं। इस तरह, आप EventHandler<T> का उपयोग कर सकते हैं और ग्राहक इस संपत्ति को प्राप्त करके और सेट करके सीमित प्रतिक्रिया तक अपने प्रतिक्रियाओं को समन्वयित भी कर सकते हैं।

+0

आपको बहुत बहुत धन्यवाद। – Jeff

+1

असहमत। (ऑब्जेक्ट प्रेषक, EventArgs ई) पैटर्न सूक्ष्म भलाई से भरा है। यहां दोनों स्वीकृत उत्तर देखें: http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/83e9f2f4-908b-4679-811d-c5b1471730d7 –

+0

ठीक है, मैं आपका बिंदु देखता हूं। – Jeff

0

मुझे लगता है कि प्रतिनिधि के बजाय लड़ाई/समारोह का उपयोग करने के बिल्कुल ठीक है।

लेकिन घटनाक्रम नहीं जा सकते कि तरह इस्तेमाल किया जा रहा। वे अनिश्चितकालीन समय बिंदु पर ट्रिगर होते हैं, इसलिए आप सभी पैरामीटर नहीं जानते हैं।

क्या तुम सच में की जरूरत है शायद है: घड़ी के लिए बहुरूपता

  1. का प्रयोग करें।
  2. उपयोग आगंतुक/ग्राहक/पर्यवेक्षक पैटर्न उनके मूल्यों को पाने के लिए।

तो कोड दिखेगा की तरह:

var theClock = new Clock(); 
theClock.AddSecondsSubscriber(new DisplayClock()); 
theClock.AddSecondsSubscriber(new LogClock()); 
theClock.RunAndExecuteVisitors(theBoolResultYouNeed => Console.WriteLine(theBoolResultYouNeed)); 
संबंधित मुद्दे