यदि आप Reactive Extensions for .NET का उपयोग कर सकते हैं, तो आप इसे सरल बना सकते हैं।
आप Observable from an event बना सकते हैं, और कोड के अपने छोटे स्निपेट को करने के लिए केवल .Take(1)
का उपयोग करके पहले तत्व को सुनें। यह इस पूरी प्रक्रिया को कोड की कुछ पंक्तियों में बदल देता है।
संपादित करें: प्रदर्शित करने के लिए, मैंने एक पूर्ण नमूना कार्यक्रम बनाया है (मैं नीचे पेस्ट करूँगा)।
मैंने एक विधि (HandleOneShot
) में देखने योग्य निर्माण और सदस्यता को स्थानांतरित कर दिया। यह आपको एक विधि विधि के साथ प्रयास करने की सुविधा देता है। प्रदर्शन के लिए, मैंने दो गुणों के साथ एक वर्ग बनाया है जो INotifyPropertyChanged लागू करता है, और के लिए पहले संपत्ति बदल गया है, जब यह होता है तो कंसोल पर लिखना।
यह आपके कोड लेता है, और करने के लिए यह परिवर्तन:
HandleOneShot<SomeEventArgs>(variableOfSomeType, "SomeEvent", e => {
// Small snippet of code here
});
ध्यान दें कि सदस्यता/सदस्यता खत्म करने के सभी पर्दे के पीछे आप के लिए अपने आप होता है। सदस्यता में मैन्युअल रूप से डालने की कोई आवश्यकता नहीं है - केवल पर्यवेक्षण की सदस्यता लें, और आरएक्स आपके लिए इसका ख्याल रखता है।
जब चलाने के लिए, इस कोड को प्रिंट:
Setup...
Setting first property...
**** Prop2 Changed! /new val
Setting second property...
Setting first property again.
Press ENTER to continue...
आप केवल एक ही, एक शॉट अपने घटना के ट्रिगर मिलता है।
namespace ConsoleApplication1
{
using System;
using System.ComponentModel;
using System.Linq;
class Test : INotifyPropertyChanged
{
private string prop2;
private string prop;
public string Prop
{
get {
return prop;
}
set
{
if (prop != value)
{
prop = value;
if (PropertyChanged!=null)
PropertyChanged(this, new PropertyChangedEventArgs("Prop"));
}
}
}
public string Prop2
{
get
{
return prop2;
}
set
{
if (prop2 != value)
{
prop2 = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Prop2"));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
class Program
{
static void HandleOneShot<TEventArgs>(object target, string eventName, Action<TEventArgs> action) where TEventArgs : EventArgs
{
var obsEvent = Observable.FromEvent<TEventArgs>(target, eventName).Take(1);
obsEvent.Subscribe(a => action(a.EventArgs));
}
static void Main(string[] args)
{
Test test = new Test();
Console.WriteLine("Setup...");
HandleOneShot<PropertyChangedEventArgs>(
test,
"PropertyChanged",
e =>
{
Console.WriteLine(" **** {0} Changed! {1}/{2}!", e.PropertyName, test.Prop, test.Prop2);
});
Console.WriteLine("Setting first property...");
test.Prop2 = "new value";
Console.WriteLine("Setting second property...");
test.Prop = "second value";
Console.WriteLine("Setting first property again...");
test.Prop2 = "other value";
Console.WriteLine("Press ENTER to continue...");
Console.ReadLine();
}
}
}
यह गंध करता है, मैं सहमत हूं। जवाब देखने के लिए तत्पर हैं। ;) – Lucero
स्थायी ईवेंट हैंडलर को जोड़ने के बारे में क्या है जो एक कतार में "एक शॉट इवेंट हैंडलर" को आमंत्रित करता है? – dtb
दिलचस्प; हमने पुशिनक्यू में कुछ ऐसा ही किया; लेकिन पुन: उपयोग के लिए समस्याएं हैं; लैम्ब्डा घटनाओं को नहीं चुन सकते हैं, और घटना के बिना, टाइपिंग इनफ्रेंसिंग एक दर्द है - और हैंडलर के संदर्भ में बिना किसी प्रकार के लैम्बडा ... मजेदार हो सकता है। –