2013-03-07 7 views
10

मैं NetworkStream.ReadAsync उपयोग करने के लिए() डेटा पढ़ने की कोशिश कर रहा हूँ बंद किए बिना NetworkStream.ReadAsync रद्द करने के लिए, लेकिन मैं ReadAsync() एक बार कहा जाता है बंद करने का तरीका नहीं मिल रही है। पृष्ठभूमि के लिए, नेटवर्कस्ट्रीम मुझे एक कनेक्टेड ब्लूटूथ क्लाइंट ऑब्जेक्ट (32Feet.NET ब्लूटूथ लाइब्रेरी से) द्वारा प्रदान किया जाता है।कैसे धारा

वर्तमान get-यह काम कोड मैं कोशिश कर रहा हूँ के नीचे है।

int bytesRead; 

while (this.continueReading) 
{ 
    bytesRead = await this.stream.ReadAsync(this.buffer, 0, (int)this.buffer.Length); 

    Console.WriteLine("Received {0} bytes", bytesRead); 
} 

Console.WriteLine("Receive loop has ended"); 

कोड ठीक प्राप्त डेटा काम करता है, और continueReading ध्वज गलत पर सेट है और डेटा प्राप्त होता है पाशन बंद हो जाएगा, लेकिन डेटा प्राप्त होने तक यह अतीत ReadAsync() लाइन आगे बढ़ना नहीं होंगे। मैं नहीं देख सकता कि डेटा प्राप्त किए बिना कॉल को कैसे रद्द किया जाए।

मुझे पता है ReadAsync की एक अधिभार जो एक CancellationToken प्रदान करता है कि वहाँ हूँ, लेकिन ऐसा लगता है कि के रूप में NetworkStream डिफ़ॉल्ट ReadAsync व्यवहार पर हावी नहीं होता, टोकन नजरअंदाज कर दिया है (NetworkStream.ReadAsync with a cancellation token never cancels देखें)।

मैं अंतर्निहित धारा को बंद करने की कोशिश की है, और इस ObjectDisposedException फेंकने के लिए इंतजार कर रहे ReadAsync कॉल का कारण बनता है, और अंतर्निहित ब्लूटूथ कनेक्शन भी बंद कर दिया जाता है। आदर्श रूप से मैं सिर्फ पढ़ने के लिए डिवाइस के साथ कनेक्शन को पूरी तरह से अलग नहीं करना चाहता हूं। यह ऐसा करने का एक साफ तरीका प्रतीत नहीं होता है, और पूरी तरह से va ReadAsync() कॉल को बाधित करने के लिए पूरी स्ट्रीम को फाड़ने के लिए अनावश्यक लगता है।

कोई सलाह?

उत्तर

1

आप NetworkStream.Read (या ReadAsync) के चारों ओर एक async आवरण है, जो भी एक cancellationtoken है कि आप पर नजर रखने और अपने आप को सम्मान कर सकते हैं प्राप्त करता है लागू कर सकते हैं। कुछ इस तरह:

Task MyCancelableNetworkStreamReadAsync(NetworkStream stream, CancellationToken ct) 
{ 
... 
if(this.stream.CanRead) 
{ 
    do 
    { 
    //check ct.IsCancellationRequested and act as needed 
    bytesRead = await this.stream.ReadAsync(this.buffer, 0, (int)this.buffer.Length); 
    } 
    while(myNetworkStream.DataAvailable); 
} 

कृपया ध्यान दें कि मैं केवल विचार वर्णन करने के लिए कोशिश कर रहा हूँ और आप Task<TResult> लौटने, साथ ही है कि क्या करते हैं के लिए विचार करने के लिए wnt सकता है {} जबकि पाश, किसी भी प्रकार या सफाई, आदि - सभी आपकी जरूरतों के हिसाब से।

मैं स्टीफन टब How do I cancel non-cancelable async operations? द्वारा लेख पर आपका ध्यान भी इंगित करता हूं और साथ ही साथ संयोजन के विस्तार के साथ भी वह ध्यान देता है।

+0

मैं DataAvailable जाँच के बारे में भूल गया था! नमूना कोड और स्टीफन टब के लेख के लिंक के लिए धन्यवाद। दोनों मेरे लिए यह हासिल करने में सहायक होंगे कि मैं बाद में हूं। धन्यवाद! – Swampie

8

आप ReadAsync रद्द नहीं कर सकते, क्योंकि आंतरिक कॉल अप्रबंधित और IOCompletion बंदरगाहों का उपयोग करता .. आपके विकल्प इस प्रकार हैं।

  1. सॉकेट का उपयोग करें। शटडाउन()। यह ऑपरेशनअबॉर्टेड की सॉकेट त्रुटि के साथ ReadAsync को वापस कर देगा।
  2. पढ़ने के लिए समय-समय पर प्रतीक्षा करें।
  3. जांच करें कि डेटा सॉकेट से पढ़ने से पहले उपलब्ध है।
+0

दुर्भाग्य से मैं सॉकेट का उपयोग नहीं कर रहा हूं, इसलिए मुझे विश्वास नहीं है कि मैं सॉकेट का उपयोग कर सकता हूं। शट डाउन। मैं एक ब्लूटूथ क्लाइंट (32Feet.NET से) बनाता हूं और BluetoothClient.Connect() को कॉल करता हूं। एक बार कनेक्ट होने पर मैं ब्लूटूथ क्लाइंट.गेटस्ट्रीम() के माध्यम से स्ट्रीम पुनर्प्राप्त करता हूं। टाइमआउट के लिए, एमएसडीएन का कहना है कि स्ट्रीम का टाइमआउट केवल सिंक्रोनस रीड() के लिए लागू होता है - रीडटाइमआउट प्रॉपर्टी और रीडएसिंक() को कभी भी समाप्त नहीं किया गया है।सॉकेट से उपलब्ध डेटा की जांच करने के बारे में थोड़ा मददगार है, और कुछ जो मैं पूरी तरह से भूल गया था। धन्यवाद – Swampie

+0

मेरी पढ़ाई समझ मुझे विफल रही। मुझे यह सुनकर खुशी हो रही है कि मेरे अन-संबंधित उत्तर अभी भी मददगार हैं। –

+0

यदि TCPClient का उपयोग करना TCPClient.Close() विधि का उपयोग लटकन readAsync() कॉल पर अपवाद बढ़ाने के लिए किया जा सकता है। –

2

मैं होने टास्क async कॉल और इस तरह का इंतजार बयान के बीच रद्द टोकन कॉल के लिए इंतजार द्वारा रद्द करने के प्रबंध कर रहा हूँ:

try { 

.... 

Task<int> readTask = input.ReadAsync(buffer, 0, buffer.Length); 
readTask.Wait(myCancellationToken); 
int readBytes= await readTask; 

.... 

} 
catch (OperationCanceledException e) 
{ 
    // handle cancellation 
}