2011-09-28 13 views
11

टीसीपी क्लाइंट से मानक BeginRead और EndRead विधियों का उपयोग करते समय और Task.Factory.FromAsync का उपयोग करते समय मेरे पास बहुत ही समान कोड है।कार्य। Factory.FromAsync और BeginX/EndX के बीच का अंतर?

यहाँ कुछ उदाहरण .. त्रुटि निवारण कोड नहीं दिखाया है।

Task.Factory.FromAsync:

private void Read(State state) 
{ 
    Task<int> read = Task<int>.Factory.FromAsync(state.Stream.BeginRead, state.Stream.EndRead, state.Bytes, state.BytesRead, state.Bytes.Length - state.BytesRead, state, TaskCreationOptions.AttachedToParent); 

    read.ContinueWith(FinishRead); 
} 

private void FinishRead(Task<int> read) 
{ 
    State state = (State)read.AsyncState; 

    state.BytesRead += read.Result; 
} 

BeginRead और EndRead साथ कॉलबैक के मानक उपयोग:

private void Read(State state) 
{ 
    client.BeginRead(state.Bytes, state.BytesRead, state.Bytes.Length - state.Bytes.Read, FinishRead, state); 
} 

private void FinishRead(IAsyncResult async) 
{ 
    State state = (State)async.AsyncState; 

    state.BytesRead += state.Stream.EndRead(async); 
} 

इन दोनों अच्छा काम है, लेकिन मैं अपने मतभेदों के उत्सुक हूँ। दोनों के लिए कोड की रेखाएं काफी समकक्ष हैं और वे दोनों एक ही कार्य करने के लिए प्रतीत होते हैं और समान दक्षता रखते हैं। कौन सा बेहतर है? आप उत्पादन कोड में क्या देखेंगे?

उत्तर

14

मैं बहुत बल्कि Task<T> देखना होगा आधारित कोड:

  • यह और अधिक आसानी से रचना के लिए प्रदान करता है; उदाहरण के लिए, एक विधि लिखना उचित रूप से आसान है जो Task<T> कार्यों का संग्रह लेता है और एक और कार्य देता है जो उन कार्यों के बहुमत के फैसले का प्रतिनिधित्व करता है। इसी तरह आप कार्यों का एक संग्रह में से किसी एक पूरा कर लिया है जब तक इंतजार कर सकते हैं आदि,
  • यह जहां निरंतरता चलाया जाता है की अधिक लचीला समयबद्धन प्रदान करता है।
  • यह काम ही प्रकार सुरक्षा और कुछ हद तक कमजोर IAsyncResultBeginRead द्वारा लौटाए प्रकार की तुलना में बहुत अधिक जानकारी के साथ वापस करने की अनुमति देता है।
  • प्रारंभ/समाप्ति मॉडल का उपयोग करने से कार्यों के साथ त्रुटि प्रबंधन और रद्दीकरण निर्दिष्ट करना आसान है। मूल रूप से आधुनिक कोड पर चल रहे इस

का लाभ लेने के लिए कि क्या आपके codebase पहले से ही व्यापक रूप Task<T> का उपयोग करता है, यह ज्यादा आसान होगा -

  • Task<T> साथ async/इंतजार सी # 5 में बेहतर भाषा समर्थन मिल रहा है .NET 4, Task<T> एक चल रहे कार्य का प्रतिनिधित्व करने का मूर्ख तरीका है। यह पहले के प्रयासों की तुलना में काम करने के लिए एक बहुत समृद्ध वातावरण है, और अगर आपको मौका मिलता है तो मैं इसे गले लगा दूंगा। आप .NET 3.5 का उपयोग कर या उससे पहले कर रहे हैं जाहिर है अगर, जीवन थोड़ा मुश्किल है, लेकिन मैं यह सोचते हैं रहा है कि जैसा कि आप सवाल पूछ रहे हैं, Task<T> एक विकल्प है ...

  • +1

    उत्तर के लिए धन्यवाद! हालांकि मैं अभी भी थोड़ा उलझन में हूँ। मुझे पता है BeginRead बहुत ही कुशल है क्योंकि कॉलबैक अवरुद्ध करने के बजाए आईओ पूर्णता पोर्ट का उपयोग करता है। क्या यह है कि इसमें दक्षता के मामले में यह अवरुद्ध नहीं होता है और केवल एक ही समय में चलता है EndRead भाग गया होगा? साथ ही, क्या आप विस्तारित कर सकते हैं कि यह बेहतर त्रुटि प्रबंधन का समर्थन कैसे करता है? क्या मुझे प्रत्येक कोड नमूने में 'राज्य' BytesRead + = 'लाइनों पर भी वही प्रयास करने की ज़रूरत नहीं है? –

    +2

    @RyanPeschel: हाँ, यह ब्लॉक नहीं करता है - अन्यथा यह व्यर्थ होगा। और नहीं, आपको एक ही कोशिश/पकड़ की आवश्यकता नहीं होगी, क्योंकि आप त्रुटि पर चलाने के लिए एक निरंतरता निर्दिष्ट कर सकते हैं, दूसरा रद्दीकरण पर चलाने के लिए, और दूसरा सफलता पर चलाने के लिए - जारी रखें के लिए ओवरलोड को देखें। आप परिणाम प्राप्त करने की कोशिश किए बिना किसी कार्य की स्थिति * परीक्षण * कर सकते हैं (टास्क.स्टैटस को देखें)। पूरी बात मूल रूप से बहुत समृद्ध है। और सी # 5 में एसिंक समर्थन अद्भुत है। –

    +0

    मैं ओवरलोड की जांच कर रहा हूं लेकिन मुझे यह नहीं दिख रहा है कि आप क्या प्राप्त कर रहे हैं। त्रुटि/रद्दीकरण होने पर चलाने के लिए मैं एक विधि कैसे निर्दिष्ट कर सकता हूं? –

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