2017-01-13 11 views
5

यह ऐसा कुछ है जिसे मैंने हमेशा थ्रेड/पृष्ठभूमिवर्कर का उपयोग किया है, लेकिन चीजों को करने के कार्य तरीके पर माइग्रेट करने का प्रयास कर रहा हूं।कार्य का उपयोग करके निरंतर मतदान

मान लें कि मेरे पास एक तृतीय पक्ष एसडीके है जिसका उपयोग मैं यूएसबी पोर्ट से बाइट पढ़ने के लिए करता हूं। उस पढ़ा गया कॉल अवरुद्ध हो रहा है और 100 एमएस के बाद समय समाप्त हो जाता है यदि कोई बाइट पढ़ा नहीं जाता है, तो शून्य वापस आ जाता है। अगर बाइट पढ़े जाते हैं, तो यह तुरंत लौटता है, बाइट [] सरणी को बाइट्स को वापस लौटाता है।

इसलिए मुझे मूल रूप से मतदान जारी रखने की आवश्यकता है, और पार्सिंग फ़ंक्शन को कॉल करके प्राप्त बाइट्स पर कार्रवाई करें। यह एक डब्ल्यूपीएफ एप्लीकेशन है, इसलिए लौटा बाइट्स को यूआई थ्रेड फ़ंक्शन में पास करने में सक्षम होना चाहिए।

ऐसा करने का सही तरीका क्या है?

private void _connectUsbButton_Click(object sender, RoutedEventArgs e) 
{ 
    ListenForUsbMessagesAsync(); 
} 

private async void ListenForUsbMessagesAsync() 
{ 
    while (true) 
    { 
     byte[] readBytes = await ReadBytesAsync(); 
     Parse(readBytes); 
    } 
} 

private Task<byte[]> ReadBytesAsync() 
{ 
    Task<byte[]> readBytesTask = Task.Run(() => 
    { 
     byte[] bytes; 

     do 
     { 
      bytes = ReadBytes(); 
     } while (bytes == null); 

     return bytes; 
    }); 

    return readBytesTask; 
} 

private byte[] ReadBytes() 
{ 
    byte[] readBytes = _usbSdk.ReadBytes(); //100ms timeout (returns null if no bytes read) 
    return readBytes; 
} 
+0

'टास्क ' एक अंतिम परिणाम के लिए है, न कि एक समय-समय पर होता है कि। –

+0

@ डैनियलए। यही कारण है कि मैं इसे थोड़ी देर (सत्य) लूप में बुलाता रहता हूं। अंतिम परिणाम कुछ बाइट पढ़ा जा रहा है। बाइट हर समय नहीं पढ़े जाते हैं, असल में ज्यादातर समय कोई बाइट पढ़ा नहीं जाता है। – Eternal21

+0

आपको इस तरह के कार्य के लिए 'थ्रेड' क्यों पसंद नहीं आया? 'कार्य को जल्दी खत्म करने के लिए डिज़ाइन किया गया है, जबकि आपके आईओ में मिनट लग सकते हैं – slawekwin

उत्तर

4

मेरे लिए ठीक लग रहा है, बस कुछ यहाँ सुझाव:

यह वही है मैं अब तक है, और यह काम करने लगता है, लेकिन मुझे यकीन है कि यह TPL का उपयोग कर काम करने के लिए सही रास्ता है बनाना चाहते है
private async Task ListenForUsbMessagesAsync(CancellationToken token) 
{ 
    while (true) 
    { 
     byte[] readBytes = await ReadBytesAsync(); 
     Parse(readBytes); 
     token.ThrowIfCancellationRequested(); 
    } 
} 

कहीं और, WPF विंडो में तरह .ctor की दुकान इस

var tokenSource = new System.Threading.CancellationTokenSource(); 

अंत में इस

की तरह अपने फ़ंक्शन को कॉल करें

इस तरह आप

tokenSource.Cancel() 

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

5

चूंकि आपका मतदान कार्य लंबे समय तक चल सकता है, इसलिए आपको इसे समर्पित थ्रेड में चलाने के बारे में सोचना चाहिए।

आप मतदान कार्य बनाते समय TaskCreationOptions.LongRunning ध्वज पास करके इसे प्राप्त कर सकते हैं।

इस तरह:

Task<byte[]> readBytesTask = Task.Factory.StartNew(() => 
    { 
     byte[] bytes; 

     do 
     { 
      bytes = ReadBytes(); 
     } while (bytes == null); 

     return bytes; 
    }, TaskCreationOptions.LongRunning); 
+0

आपके सुझाव को जोड़ने का प्रयास किया, लेकिन यह 'रिटर्न बाइट्स' लाइन पर एक कंपाइलर त्रुटि के साथ समाप्त होता है: CS0029 \t टाइप 'बाइट []' को 'System.hreading.Tasks.Task' में परिवर्तित नहीं कर सकता है – Eternal21

+1

इसे ठीक करने की आवश्यकता है कार्य का उपयोग करने के लिए। फैक्ट्री एक कार्यप्रणाली विकल्प को पारित करने में सक्षम होने के लिए (भूलें कि यह अधिभार केवल फैक्ट्री के तहत उपलब्ध है) – barakcaf

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