2010-10-29 15 views
6

मैं रोबोट नियंत्रक के लिए एक रैपिंग लाइब्रेरी पर काम कर रहा हूं, जो ज्यादातर पी/इनवॉक कॉल पर निर्भर करता है।Async P/कॉल को कॉल करें

हालांकि, रोबोट, जैसे होमिंग, या मूवमेंट के लिए बहुत सारी कार्यक्षमता काफी समय लेती है, और चलते समय थ्रेड लॉक करते हैं।

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

public Task<bool> HomeAsync(Axis axis, CancellationToken token) 
{ 
    return Task.Factory.StartNew(() => Home(axis), token); 
} 

.NET में Async मॉडल के रूप में पर MSDN लेख में से अधिकांश अभी, ज्यादातर पहले से ही Async कार्यक्षमता (जैसे File.BeginRead के रूप में और इतने पर) होने पुस्तकालयों पर प्रसारण किया जाता है। लेकिन मुझे वास्तव में एसिंक कार्यक्षमता को वास्तव में कैसे लिखना है, इस बारे में अधिक जानकारी नहीं मिल रही है।

+0

आप किस प्रकार का इंटरफ़ेस उपयोग कर रहे हैं? या यह एक पुस्तकालय है जिसे एक विशिष्ट इंटरफेस से स्वतंत्र रूप से बनाया जाना है? –

+0

मान लीजिए कि आप यूआई इंटरफ़ेस का मतलब है, इसके ऊपर एप्लिकेशन का निर्माण WPF है। लेकिन मैं इसे लाइब्रेरी स्तर पर संभालना पसंद करूंगा, इसलिए यूआई टीम को थ्रेडिंग के बारे में ज्यादा चिंता करने की ज़रूरत नहीं है। –

+1

रोबोट इंटरफ़ेस सामान्य रूप से इस तरह से काम नहीं करता है। आप पूरी तरह से डिवाइस पर नियंत्रण खो देंगे, आप होमिंग कदम को भी रोक नहीं सकते। एक होम कमांड आम तौर पर सिर्फ होमिंग चाल शुरू करता है, फिर आप इसे पूरा करते समय मतदान करेंगे या सिग्नल प्राप्त करेंगे। इस तरह से करने के लिए प्रतिबद्ध करने से पहले इंटरफ़ेस में क्या उपलब्ध है इसकी जांच करें। –

उत्तर

4

क्या आपने कभी async delegates को आजमाया है? मेरा मानना ​​है कि इससे कुछ भी आसान नहीं है।

यदि आपकी थ्रेड-अवरुद्ध विधि void Home(Axis) है तो आपके पास पहले प्रतिनिधि प्रकार को परिभाषित करना है, यानी। delegate void HomeDelegate(Axis ax), फिर होम विधि के पते पर इंगित होमडिलेगेट के नए उदाहरण की BeginInvoke विधि का उपयोग करें।

[DllImport[...]] //PInvoke 
void Home(Axis x); 

delegate void HomeDelegate(Axis x); 

void main() 
{ 
    HomeDelegate d = new HomeDelegate(Home); 
    IAsyncResult ia = d.BeginInvoke(axis, null, null); 
    [...] 
    d.EndInvoke(ia); 
} 

ध्यान में रखना दें कि EndInvoke कहीं का उपयोग कर (धागा अवरुद्ध जब तक विधि अंत में खत्म हो गया है, हो सकता है IAsyncResult.Completed संपत्ति के मतदान के साथ) का बहुत उपयोगी है की जाँच करने के लिए यदि आपके async कार्य वास्तव में कर दिया गया है पूरा कर लिया है। हो सकता है कि आप अपने रोबोट को अपनी बांह खोलने और ग्लास छोड़ने तक ग्लास छोड़ दें, आपको पता है ;-)

+1

और आपको अब प्रतिनिधि प्रकारों को परिभाषित करने की भी आवश्यकता नहीं है। बस 'एक्शन ' का उपयोग करें। – erikkallen

+0

हाँ, ठीक है! मैं एक्शन भूल गया !! :- डी –

+0

मेरा मानना ​​है कि कार्य समानांतर लाइब्रेरी कार्य वर्ग में सभी को लपेटती है, नहीं? –

1

मेरी पहली प्रतिक्रिया यह है कि पुस्तकालय में आपको ऐसा कुछ नहीं करना चाहिए। प्राथमिक कारण यह है कि इस तरह के सिस्टम को लागू करने का तरीका पुस्तकालय पर आपके द्वारा बनाए जा रहे इंटरफ़ेस के प्रकार पर निर्भर हो सकता है।

उस ने कहा, आपके पास मूल रूप से दो विकल्प हैं। पहला IAsyncResult है। इसका एक अच्छा विवरण http://ondotnet.com/pub/a/dotnet/2003/02/24/asyncdelegates.html पर पाया जा सकता है।

दूसरा विकल्प कॉलबैक ईवेंट के साथ कमांड बनाना है। उपयोगकर्ता कमांड क्लास बनाता है और उस पर कॉलबैक सेट करता है। फिर, आप कमांड को ThreadPool पर शेड्यूल करते हैं और कमांड निष्पादित करने के बाद, आप उस ईवेंट को बढ़ाते हैं।

.NET ढांचे के पुराने इंटरफेस ने मुख्य रूप से IAsyncResult दृष्टिकोण लागू किया, जहां नए इंटरफेस ईवेंट कॉलबैक दृष्टिकोण को कार्यान्वित करते हैं।

+0

और थ्रेडपूल पर किसी आइटम को कतार में यूआई थ्रेड को अवरुद्ध नहीं करता है? यहां तक ​​कि यदि मेरे पास ऑपरेशन होने पर ईवेंट होने की घटनाएं होती हैं, तो यूआई अवरुद्ध करने से बचने के लिए मुझे सभी कॉलों को थ्रेड में लपेटने की ज़रूरत है। –

+0

इसे 'थ्रेडपूल' पर कतार में अवरुद्ध नहीं करता है, नहीं। कॉलबैक इंटरफ़ेस का उपयोग करने का पूरा कारण यह है कि आप UI इंटरफ़ेस कार्यान्वयन में सिंक्रनाइज़ेशन छोड़ सकते हैं। आप यूआई को सिग्नल करने का एक तरीका प्रदान करते हैं जो आप कर चुके हैं, और यूआई इसे वहां से ले जाता है। एक और फायदा यह है कि कॉलबैक वैकल्पिक हैं, इसलिए जब यूआई को अधिसूचना की आवश्यकता नहीं होती है, तो यह सिर्फ कॉलबैक पंजीकृत नहीं करता है और केवल आग और भूल जाता है। –

+0

हाँ, लेकिन कॉलबैक मॉडल भी मेरा पहला सुझाव था। मैं इसे लेता हूं कि लोग टीपीएल से अपरिचित हैं? –

3

कुछ महान चर्चा के बाद, मुझे लगता है कि ऐसा कुछ सुनहरा माध्यमिक होगा।

public void HomeAsync(Axis axis, Action<bool> callback) 
{ 
    Task.Factory 
     .StartNew(() => Home(axis)) 
     .ContinueWith(task => callback(task.Result)); 
} 

यह दोनों दुनिया के सर्वश्रेष्ठ का उपयोग कर रहा है, मुझे लगता है।

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