2008-11-14 22 views
38

से कस्टम ईवेंट कैसे बढ़ाएं मेरे पास एक स्थिर वर्ग है जिसे मैं उस वर्ग की स्थिर विधि के भीतर एक प्रयास पकड़ ब्लॉक के हिस्से के रूप में एक ईवेंट को उठाना चाहता हूं।स्टेटिक क्लास

उदाहरण के लिए इस विधि में मैं पकड़ में एक कस्टम घटना को उठाना चाहता हूं।

public static void saveMyMessage(String message) 
{ 
    try 
    { 
     //Do Database stuff 
    } 
    catch (Exception e) 
     { 
       //Raise custom event here 
     } 
} 

धन्यवाद।

उत्तर

88

महत्वपूर्ण: उदाहरणों से एक स्थिर घटना की सदस्यता लेने के बारे में बहुत सावधान रहें। स्टेटिक-टू-स्टेटिक ठीक है, लेकिन एक स्थिर घटना से एक उदाहरण हैंडलर तक एक सदस्यता एक उदाहरण (पढ़ने: बहुत खतरनाक) तरीका है जो उस उदाहरण को हमेशा के लिए जिंदा रखने के लिए है। जीसी लिंक देखेंगे, और जब तक आप सदस्यता समाप्त नहीं करेंगे (या वीक रेफरेंस की तरह कुछ उपयोग करें) तब तक इंस्टेंस एकत्र नहीं करेंगे।

स्थिर घटनाओं बनाने के लिए पैटर्न, isntance घटनाओं के रूप में एक ही है बस static साथ:

public static event EventHandler SomeEvent; 

बनाने के जीवन को आसान (शून्य जाँच फिर से), यहाँ एक उपयोगी चाल एक छोटी सी हैंडलर जोड़ने के लिए है:

public static event EventHandler SomeEvent = delegate {}; 

तो फिर तुम बस अशक्त की जांच के बिना यह आह्वान कर सकते हैं:

SomeEvent(null, EventArgs.Empty); 

ध्यान दें कि प्रतिनिधि उदाहरण अपरिवर्तनीय हैं, और डी-रेफरेंसिंग थ्रेड-सुरक्षित है, यहां कभी भी दौड़ की स्थिति नहीं है, और लॉक करने की कोई आवश्यकता नहीं है ... जब हम डी-रेफरेंस का आह्वान करते हैं तो कभी भी सब्सक्राइब किया जाता है।

(अपने स्वयं के ईवेंट-तर्क आदि के लिए समायोजित करें)। यह चाल उदाहरण घटनाओं के लिए समान रूप से लागू होती है।

+0

अपना उत्तर पढ़ते समय, आपने कहा, "एक स्थिर घटना से एक आवृत्ति हैंडलर की सदस्यता एक उदाहरण है जो उस घटना को हमेशा के लिए जिंदा रखने के लिए एक शानदार तरीका है", मुझे लगता है कि यह हमेशा इष्टतम नहीं होगा। यदि, कहें, मैं चल रहा है, तो फॉर्म सेटिंग्स को स्टोर करने के लिए एक स्थिर वर्ग का उपयोग कर रहा हूं, यह स्थिर है क्योंकि यह स्थिर है, और इसमें कई प्रतियां नहीं हो सकती हैं? (नौसिखिया प्रोग्रामर, खराब शब्दावली को क्षमा करें) – Josh

+0

@ जोश "शानदार तरीका" का अर्थ "वास्तव में एक खतरनाक तरीका" था - मैंने इसे स्पष्ट किया है। यदि आपके पास केवल एक सदस्यता है, तो स्थिर बनाम उदाहरण के बावजूद यह एक बड़ी समस्या नहीं है। खतरनाक हिस्सा तब आता है जब प्रत्येक इंस्टेंस एक स्थिर घटना के लिए (कहें), या दीर्घकालिक वस्तु पर एक ईवेंट की सदस्यता लेता है, और कभी भी सदस्यता समाप्त नहीं करता है। हे पस्टो: मेमोरी क्लोग। –

+1

"एक स्थिर घटना से एक उदाहरण हैंडलर तक सदस्यता" क्या यह इस उद्देश्य पर लिखा गया है? मेरा मानना ​​है कि यह "उदाहरण के हैंडलर से एक स्थैतिक घटना" से सदस्यता होना चाहिए। –

0

नोट: VS2008, सी #

बस के रूप में आप सामान्य रूप से स्थिर वर्ग के भीतर है, लेकिन स्थिर के रूप में घटना को चिह्नित करने के लिए सुनिश्चित हो जाएगा एक घटना की घोषणा:

public static event EventHandler Work; 

तो बस आप के रूप में यह करने के लिए सदस्यता सामान्य रूप से होगा। बस कोड जैसे का उपयोग कर एक ईवेंट सक्रिय नहीं है

public class Test 
{ 
    public void OnError(object sender, ErrorEventArgs args) 
    { 
     Console.WriteLine(args.Message); 
    } 
} 

Test t = new Test(); 
Service.OnError += t.OnError; 
Service.SaveMyMessage("Test message"); 
+0

पुन "जैसा कि आप सामान्य रूप से करेंगे" - आपको स्थिर घटनाओं के साथ अधिक सावधान रहना होगा, विशेष रूप से पुनः सदस्यता लेना। यह सी # बीटीडब्ल्यू के किसी भी संस्करण में काम करेगा। –

10

आपकी घटना भी स्थिर करने की आवश्यकता होगी:

public class ErrorEventArgs : EventArgs 
{ 
    private Exception error; 
    private string message; 

    public ErrorEventArgs(Exception ex, string msg) 
    { 
     error = ex; 
     message = msg; 
    } 

    public Exception Error 
    { 
     get { return error; } 
    } 

    public string Message 
    { 
     get { return message; } 
    } 
} 

public static class Service 
{ 
    public static EventHandler<ErrorEventArgs> OnError; 

    public static void SaveMyMessage(String message) 
    { 
      EventHandler<ErrorEventArgs> errorEvent = OnError; 
     if (errorEvent != null) 
     { 
      errorEvent(null, new ErrorEventArgs(null, message)); 
     } 
    } 
} 

और उपयोग:

if(null != ExampleEvent) 
{ 
    ExampleEvent(/* put parameters here, for events: sender, eventArgs */); 
} 

क्योंकि इसमें जब आप शून्य के लिए ईवेंट की जांच करते हैं और जब आप वास्तव में घटना को आग लगाना (किसी भी जाति की स्थिति के बारे में चिंता करने के लिए अनिवार्य रूप से बिना

MyEvent exampleEventCopy = ExampleEvent; 
if(null != exampleEventCopy) 
{ 
    exampleEventCopy(/* put parameters here, for events: sender, eventArgs */); 
} 

यह exampleEventCopy, जिसे फिर आप सार्वजनिक समारोह की एक स्थानीय-केवल संस्करण के रूप में उपयोग कर सकते हैं में किसी भी घटना ग्राहकों कॉपी जाएगा, यह: इसके बजाय एक साधारण भिन्नता का उपयोग यह संभव है कि एक अन्य धागा आपको सार्वजनिक घटना की जांच करने के ठीक बाद पूर्व-खाली कर सकता है और घटना से सभी ग्राहकों को हटाने के लिए आगे बढ़ सकता है, जिससे घटना की आगामी फायरिंग एक अपवाद फेंकने के लिए, स्थानीय-केवल प्रतिलिपि का उपयोग कर, आप किसी अन्य थ्रेड को ग्राहकों को हटाने की संभावना से बचते हैं, क्योंकि स्थानीय चर तक पहुंचने का कोई तरीका नहीं है)।

+0

+1 यह बहुत लंबा रहा है क्योंकि मुझे ईवेंट हैंडलिंग लिखना पड़ा है, इसके लिए मैं सिंटैक्स भी याद नहीं कर सका। जाहिर है क्योंकि मैं केवल 2.0 वाक्यविन्यास के बारे में सोच सकता था (पिछली बार मुझे एक लिखना था) और भूल गए कि उन्होंने इसे 3.5 –

6

कई लोगों कोड उदाहरण ऊपर की पेशकश की है,:

+7

में जोड़ा एक आसान फिक्स है: सार्वजनिक स्थैतिक घटना EventHandler कार्य = प्रतिनिधि {}; अब यह कभी शून्य नहीं है और आप इसे अभी भी बुला सकते हैं। थोड़ा आलसी, लेकिन चोट पहुंचाने के लिए पर्याप्त नहीं है। –

+1

@ मार्क प्रतिनिधियों की सूची की प्रतिलिपि बनाने और एक शून्य जांच करने की तुलना में, मुझे लगता है कि एक "कुछ भी नहीं" प्रतिनिधि होना तेज और सरल है। उपरोक्त उत्तर के लिए धन्यवाद। – MindJuice

0

बस "प्रतिनिधियों को अपरिवर्तनीय" जोड़ने के लिए, इसलिए, निम्न पंक्ति के ऊपर दिए गए उदाहरण में दिखाए गए प्रतिनिधि की एक प्रति प्राप्त होती है।

EventHandler<ErrorEventArgs> errorEvent = OnError; 
संबंधित मुद्दे