2012-10-24 13 views
6

मुझे लगता है कि मुझे कुछ बुनियादी याद आ रहा है। मेरी समस्या यहाँ है।एक क्रिया के साथ एक कार्य बनाएँ <T>

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

void DoWork(MyClass obj) {} //My action that accepts a parameter of type 'MyClass' 

MyClass obj = new MyClass(); 
Action<MyClass> action = DoWork; //action that points to the method 
Task task = new Task(action,obj); //task that would execute 'DoWork' with 'obj' as the parameter when I call Start. 

स्पष्ट रूप से यह संकलित नहीं करता है। ऐसा लगता है कि मैं केवल एक कार्य के लिए Action<object> का उपयोग कर सकता हूं और Action<T> नहीं कर सकता और फिर 'ऑब्जेक्ट' को मेरी विधि के अंदर टी में डाल सकता हूं।

मैं सबसे प्रभावी और कुशलता से क्या हासिल कर सकता हूं?

उत्तर

4

आप

Action<Object> action = o => DoWork((MyClass)o); 
Task task = new Task(action, obj); 

आप .NET 4.0 या इसके बाद के संस्करण उपयोग कर रहे हैं इस्तेमाल कर सकते हैं, तो आप Contravariance उपयोग कर सकते हैं एक नया प्रतिनिधि

 
//INCORRECT Code, casts InvalidCastException at runtime 
Action action = DoWork; 
Task task = new Task((Action)action, obj); 

शुरू करने के बिना अपने लक्ष्य को प्राप्त करने

ईडीआई टी:

@svick के लिए धन्यवाद, यह इंगित करने के लिए कि दूसरा विकल्प सही नहीं है: मैं बहुत व्यस्त था, चाहे कार्रवाई सह-या contravariant (वास्तव में contravariant है, मैं इस बारे में सही था कम से कम) कि मैंने निरीक्षण किया है कि मुझे इस मामले में कोविरिएन्स की आवश्यकता होगी।

contravariance मतलब है कि आप स्पष्ट कास्टिंग बिना

Action<object> action1 = someAction; 
Action<SubClass> action2 = action1; 

कर सकते हैं।

+0

किसी भी कारण है कि इस एपीआई का हिस्सा नहीं है? – alwayslearning

+0

'टास्क '.NET 4.0 के बाद से ढांचे में है, इसलिए मुझे लगता है कि क्वालीफायर आवश्यक नहीं है। – svick

+0

इसके अलावा, यह नहीं है कि contravariance कैसे काम करता है, आप 'एक्शन ' 'एक्शन 'पर जा सकते हैं, लेकिन दूसरी तरफ नहीं। – svick

4

तुम भी सीधे उपयोग कर सकते हैं:

MyClass obj = new MyClass(); 
Task task = Task.Run(() => DoWork(obj)); 
+0

बस उल्लेख करने के लिए: इसका थोड़ा अलग अर्थ है। यदि आप कार्य शुरू करने से पहले * चर * * obj' बदलते हैं, या प्रतिनिधि के नाम से 'कार्य' तर्क से पहले भी, 'DoWork' नई ऑब्जेक्ट पर काम करेगा। यह उन बगों का कारण बन सकता है जो ट्रैक करने में बहुत मुश्किल हैं। एक क्लासिक स्थिति होगी, यदि आप इसे लूप 'foreach (MyObjList में MyClass o) के अंदर उपयोग करते हैं {(नया कार्य (() => DoWork (o))) प्रारंभ करें(); } '। – MartinStettner

+0

@ मार्टिनस्टेटनर, _ "क्लासिक स्थिति होगी, अगर आप इसे लूप के अंदर उपयोग करते हैं" _ foreach loop बदल दिया गया है और अब ऐसा कोड सही है। – Qwertiy

संबंधित मुद्दे