2010-02-07 18 views
5

मैं हाल ही में एक सब कुछ सीखने की कोशिश कर रहा हूं जो मैं कर सकता हूं। नेट मल्टीथ्रेडिंग। (इसमें बेहतर हो रहा है, लेकिन अभी भी ऐसा लगता है कि सीखने के लिए बहुत कुछ है)। अभी मैं एपीएम (अतुल्यकालिक प्रोग्रामिंग मॉडल) जो आमतौर पर इस के रूप में जाना जाता है पर ध्यान केंद्रित कर रहा हूँ:क्या यह असीमित प्रोग्रामिंग मॉडल को लागू करने का एक अच्छा तरीका है?

//non async method 
public int DoSomeWork(int arg) 
{ 
    //do something and return result 
} 

//async version 
public IAsyncResult BeginDoSomeWork(int arg, AsyncCallback callback, object @object) 
{ 

} 

public int EndDoSomeWork(IAsyncResult result) 
{ 

} 

अब मान लें कि मैं कुछ पुस्तकालय लिख रहा हूँ, और मैं कौन लेने वाली है किसी को भी इस कार्यक्षमता को बेनकाब करना चाहते हैं मेरी एपीआई, मैं इस पैटर्न को लागू करने के तरीकों के बारे में सोच रहा था। IAsyncResult इंटरफ़ेस को कार्यान्वित करना एक संभावना है, लेकिन यह काफी जटिल लगता है। मेरा सवाल है, अगर प्रतिनिधि का उपयोग करना एक स्वीकार्य समाधान है।

public class MyClass 
{ 
    private Func<int, int> func; 

    //non async method 
    public int DoSomeWork(int arg) 
    { 
     //do something and return result 
    } 

    //async version 
    public IAsyncResult BeginDoSomeWork(int arg, AsyncCallback callback, object @object) 
    { 
     this.func = new Func<int, int>(DoSomeWork); 
     var asyncResult = this.func.BeginInvoke(arg,callback,object); 
     return asyncResult; 
    } 

    public int EndDoSomeWork(IAsyncResult result) 
    { 
     return this.func.EndInvoke(result); 
    } 
} 

असल में, हर प्रतिनिधि इसे में सही पके हुए BeginXxx और EndXxx कार्यक्षमता है: क्या मुझे लगता है कि मतलब यह है। क्या इसका लाभ उठाना ठीक है और केवल IAsyncResult का पर्दाफाश करें, या इसमें कुछ गड़बड़ है जिसके बारे में मैं सोच नहीं रहा हूं।

उत्तर

1

मुझे लगता है कि यह एपीएम को लागू करने का एक अच्छा तरीका है, लेकिन इस समय आपको प्रति उदाहरण एक से अधिक असीमित कॉल के साथ एक त्रुटि मिलेगी।

आप प्रतिनिधि उपयोग को बाहरी क्यों नहीं करते?

क्या मेरा मतलब है, की तुलना में अगर आप सिर्फ अपनी कक्षा में वास्तविक तर्क रखा, लेकिन कोई भी व्यक्ति आपकी प्रणाली को बुलाती है तो चलो करते हैं:

MyClass c = new MyClass(); 
Func<int, int> f = c.DoSomeWork; 
IAsyncResult ar1 = f.BeginInvoke(1, null, null); 
IAsyncResult ar2 = f.BeginInvoke(2, null, null); 
//... 

मुझे लगता है कि मैं क्या कर रहा हूँ की वकालत भी लागू नहीं किया गया है एपीएम स्वयं, लेकिन केवल उन लोगों को अनुशंसा करते हैं जो आपकी विधि को कॉल करते हैं कि वे प्रतिनिधिों में निर्मित एपीएम का उपयोग करते हैं।

0

आईएमएचओ, मुझे नहीं लगता कि आपकी एसिंक विधि कोई मूल्य जोड़ती है, इसलिए ग्राहक को यह तय करने दें कि क्या यह आपकी विधि को असीमित रूप से कॉल करेगा या नहीं।

+0

यह सिर्फ एक उदाहरण था। वास्तविक कार्यान्वयन को अनदेखा करें (जो स्वीकार्य रूप से बेवकूफ और व्यर्थ दिखता है), मैं प्रतिनिधि का उपयोग करने के बारे में पूछ रहा हूं और यह IAsyncResult है। – BFree

+0

क्योंकि एक सिंक्रोनस और एसिंक्रोनस संस्करण दोनों प्रदान किए जाते हैं क्योंकि क्लाइंट अभी भी वह निर्णय लेता है। ओपी इस बात से अधिक चिंतित है कि चुनी गई विधि एपीएम को लागू करने का एक अच्छा तरीका है या नहीं। – Crippledsmurf

+0

@BFree, मैं अब सी। – Benny

0

मुझे लगता है कि अगर यह कुछ और नहीं है तो यह एक बहुत ही वैध व्यायाम है। मैं भी एक एसिंक्रोनस 'प्रतिनिधि' हैंडलर पर काम कर रहा हूं। आप लचीलापन बढ़ा सकते हैं, और आप एसिंक मॉडल के बारे में बहुत कुछ सीखेंगे।

मुझे पता है कि यह SO question इसमें कुछ लिंक व्यायाम शामिल है। हालांकि, यह आपको थोड़ा और मजबूत बनाने के लिए अभिव्यक्ति पेड़ों का उपयोग करने पर एक विचार दे सकता है। मैंने अभी तक इस विषय में डुबकी डाली है और आपको अधिक ठोस जानकारी प्रदान की है।

यहां एसिंक्रोनस विधियों को प्रकाशित करने पर मेरे पुराने कोड के एक टुकड़े का नमूना है। यह दिनांक सीखने प्रतिबिंब और कुछ रोचक कार्यान्वयन में अभ्यास है। क्या इसके लायक है के लिए ले लो, लेकिन यह कुछ विचारों के साथ आपकी मदद कर सकता है:

public delegate void delVoidMethod(params object[] args); 

/// <summary> 
/// Publishes an asynchronous method to the delegate collection. 
/// </summary> 
/// <param name="methodOwner">Target object owning the delegated method.</param> 
/// <param name="method">The delegated method.</param> 
/// <param name="callback">The method designated as a callback delegate.</param> 
/// <param name="ptr">The delegated method's runtime handle.</param> 
/// <returns>True if publishing was successful.</returns> 
public bool PublishAsyncMethod(object target , MethodInfo method , 
    MethodInfo callback , out IntPtr ptr) 
{ 
    try 
    { 
     ptr = method.MethodHandle.Value; 

     delVoidMethod dMethod = (delVoidMethod)Delegate.CreateDelegate 
      (typeof(delVoidMethod) , target , method); 
     AsyncCallback callBack = (AsyncCallback)Delegate.CreateDelegate 
      (typeof(AsyncCallback) , target , callback); 

     handlers[ptr] = new DelegateStruct(dMethod , callBack); 

     Logger.WriteLine("Delegate : {0}.{1} -> {2}.{3} published." , 
      method.DeclaringType.Name , method.Name , 
      callback.DeclaringType.Name , callback.Name); 
     return true; 
    } 
    catch (ArgumentException ArgEx) 
    { 
     Logger.Write(DH_ERROR , ERR_MSG , 
      ArgEx.Source , ArgEx.InnerException , ArgEx.Message); 
    } 
    catch (MissingMethodException BadMethEx) 
    { 
     Logger.Write(DH_ERROR , ERR_MSG , 
      BadMethEx.Source , BadMethEx.InnerException , BadMethEx.Message); 
    } 
    catch (MethodAccessException MethAccEx) 
    { 
     Logger.Write(DH_ERROR , ERR_MSG , 
      MethAccEx.Source , MethAccEx.InnerException , MethAccEx.Message); 
    } 

    ptr = IntPtr.Zero; 

    return false; 
} 
0

बिल्कुल इसके साथ कुछ भी गलत नहीं है, लेकिन यह थोड़ा व्यर्थ लगता है।

आप अनिवार्य रूप से Facade pattern को कार्यान्वित कर रहे हैं, लेकिन इंटरफ़ेस को कोई आसान नहीं बना रहे हैं। यह कॉल बेहतर बनाने के लिए बेहतर हो सकता है (आपकी विशिष्ट स्थिति के आधार पर) कॉल को सरल बनाने के लिए अपने स्वयं के वर्ग जोड़ने के लिए AsyncCallback और IAsyncResult कॉल को आपके वर्गों में उपयोग की जाने वाली गुणों को अधिक सटीक रूप से प्रतिबिंबित करने के लिए।

+0

मुझे फेकाडे पैटर्न को परिभाषित करने वाली गोलियों की तुलना में ओपी क्या कर रहा है, इसकी समानताओं को नहीं देखता है। – IAbstract

0

मैं व्यक्तिगत रूप से एक घटना का उपयोग करना पसंद करता हूं जब एसिंक्रोनस प्रक्रिया समाप्त होती है, यदि वर्ग को अन्य लाइब्रेरी द्वारा उपयोग किया जाता है, तो AsyncOperation क्लास और SendOrPostCallback प्रतिनिधि का उपयोग करके यह सुनिश्चित करने के लिए कॉलर्स थ्रेड पर ईवेंट उठाए जाते हैं। यूआई को बाधित करें। हालांकि यदि असेंबलीस ऑपरेशन को एक ही असेंबली में निष्पादित किया जाना है, तो मैं एसिंक्रोनस कॉल को कैसे परिभाषित करना परिभाषित करने के लिए कॉलिंग कोड पसंद करता हूं।

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

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