2011-09-04 27 views
6

सारांश: क्या यह भी संभव है?मैं HttpWebRequest को यथासंभव समकालिक रूप से व्यवहार करने के लिए कैसे प्राप्त कर सकता हूं?

unit test function on ui thread: 
- creates a background thread 
- starts the thread 
- waits for it to complete (function does not exit until it completes!) 

background thread: 
- opens an http stream 
- reads a url from the web 
- terminates 

मेरे संदेह: ढांचा एसिंक्रोनस रूप से कुछ आंतरिक संदेश कतार पर परिणाम डालता है और इस प्रकार की प्रतिक्रिया कॉलबैक तक ui धागा के ढेर unwinds और ढेर पंप करने के लिए कुछ ui धागा समारोह को जाता है कभी नहीं बुलाया जाएगा।


पूरी कहानी:

मैं एक ऐप्लिकेशन है जो विभिन्न स्रोतों से एक धारा, उनमें से एक एक सरल http url से किया जा रहा है बनाने की आवश्यकता है पोर्टिंग कर रहा हूँ। मैं इसे पृष्ठभूमि धागे पर कर रहा हूं, और आदर्श रूप में मैं इसे 100% सिंक्रनाइज़ तरीके से व्यवहार करना चाहता हूं, केवल आवश्यकता होने पर ब्लॉक करें (यह ठीक है क्योंकि यह पृष्ठभूमि थ्रेड पर है)।

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

मैं निम्न आलेख भर में ठोकर खाई है http://pieterderycke.wordpress.com/2011/05/23/adding-synchronous-methods-to-webrequest-on-windows-phone-7/, जो http वेब अनुरोध तुल्यकालिक बनाने के लिए एक समाधान पता चलता है। लेकिन जैसा कि इसे कार्यान्वित किया गया है, मुझे प्रोटोकॉलविलेशन अपवाद मिलता है। मैंने बाद में BeginGetRequestStream() के बजाय BeginGetResponse() का उपयोग करने के लिए कोड में संशोधन किया है, और ऐसा लगता है कि यह अब अपवाद का कारण नहीं है।

लेकिन ऐसा लगता है कि पृष्ठभूमि धागा अब अनिश्चित काल तक अवरुद्ध है। मेरे यूई थ्रेड I लूप पर, थ्रेड कर रहा है। नींद (10) क्योंकि मैं एक यूनिट टेस्ट फ़ंक्शन में हूं, मेरे कॉलबैक को कॉल करने का इंतजार कर रहा हूं। क्या यह संभव है कि कॉलबैक यूनिट टेस्ट फ़ंक्शन रिटर्न तक नहीं बुलाया जाएगा और यूई थ्रेड को संदेशों को पंप करने का मौका है? यदि हां, तो मैं इसे पंप करने के लिए मजबूर कर सकता हूं ताकि मैं यूनिट टेस्ट रूटीन में छोड़ा गया जहां मैं जारी रख सकूं?

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

एमएसडीएन दस्तावेज़ केवल आपको एसिंच कॉल करने के तरीके दिखाते हैं। और वे यह भी उल्लेख करते हैं कि "BeginGetResponse विधि को कुछ सिंक्रोनस सेटअप कार्यों को पूरा करने की आवश्यकता होती है" ... "आमतौर पर कई सेकंड" ... लेकिन "60 सेकंड या अधिक समय लग सकता है"। यह ui धागे पर निष्पादित करने के लिए बहुत बुरा लगता है। http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx

कृपया मदद करें!

यहाँ मेरी कोड है:

using System.Net; 
using System.Threading; 
using System; 
using System.IO; 

namespace Blah 
{ 
    // http://pieterderycke.wordpress.com/2011/05/23/adding-synchronous-methods-to-webrequest-on-windows-phone-7/ 
    // Creates synchronous web requests. 
    // Must not be called on UI threads. 

    public static class WebRequestExtensions 
    { 
    public static Stream GetRequestStream(this WebRequest request) 
    { 
     AutoResetEvent autoResetEvent = new AutoResetEvent(false); 

     IAsyncResult asyncResult = null; 
     { 
     // http://stackoverflow.com/questions/253549/how-do-i-use-httpwebrequest-with-get-method 

     if (request.Method == "GET") 
     { 
      asyncResult = request.BeginGetResponse(
      r => autoResetEvent.Set(), null); 
     } 
     else 
     { 
      asyncResult = request.BeginGetRequestStream(
      r => autoResetEvent.Set(), null); 
     } 
     } 

     // Wait until the call is finished 
     autoResetEvent.WaitOne(); 

     return request.EndGetRequestStream(asyncResult); 
    } 
    } 
} 

मैं भी हाल ही में http://www.eggheadcafe.com/tutorials/aspnet/91f69224-3da5-4959-9901-c5c717c9b184/making-silverlight-emulate-synchronous-requests.aspx भर में ठोकर खाई है, लेकिन इस एक ही समस्या दर्शाती है। ऐसा लगता है कि जब तक यूई थ्रेड स्टैक को वापस नहीं लौटाता तब तक मुझे अपना कॉलबैक नहीं मिलता है ... मैं कहीं किसी फ्रेमवर्क संदेश कतार की गंध कर सकता हूं, क्या मैं सही हूँ?

धन्यवाद

+0

कोड मुझे ठीक लग रहा है। मुझे लगता है कि ProtocolViolationException आपको कुछ बता रहा है! आप किस यूआरएल का उपयोग कर रहे हैं? पूरा अपवाद संदेश क्या था? – ColinE

+0

धन्यवाद, लेकिन जैसा कि मैंने कहा था कि प्रोटोकॉल विलोएशन अपवाद दूर हो गया है क्योंकि मैंने अनुरोध को बदल दिया है। अनुरोध के साथ BginginGetRequestStream()। BginginGetResponse()। – swinefeaster

उत्तर

3

HTTP प्रतिसाद प्रसंस्करण के रूप में अवरुद्ध यह पूरा करने से अनुरोध कर पाएगा, यूआई धागा इस्तेमाल करता है। वैकल्पिक रूप से,

using System; 
using System.Net; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using Microsoft.Silverlight.Testing; 

[TestClass] 
public class WebRequestsTests : WorkItemTest 
{ 
    [TestMethod, Asynchronous] 
    public void TestWebRequest() 
    { 
     var webRequest = WebRequest.CreateHttp("http://www.stackoverflow.com"); 

     webRequest.BeginGetResponse(result => 
     { 
      EnqueueCallback(() => 
      { 
       WebResponse response = webRequest.EndGetResponse(result); 

       // process response 

       TestComplete(); // async test complete 
      }); 
     }, null); 
    } 
} 

आप आरएक्स (व्यक्तिगत रूप से मुझे क्या करना है), मैं हाल ही में उपयोग करने के लिए देख रहे हैं:

मान लिया जाये कि आप सिल्वरलाइट यूनिट परीक्षण फ्रेमवर्क बिट्स के प्रयोग कर रहे हैं, आप अपने परीक्षण [Asynchronous] के रूप में चिह्नित कर सकते हैं SL परीक्षण ढांचे का उपयोग करते समय Rx- आधारित एसिंक्रोनस परीक्षण क्लीनर बनाने के तरीके पर did a blog post

+0

@ स्विसफेस्टर - मेरे उत्तर की पहली पंक्ति आपके प्रश्न की सीधी प्रतिक्रिया है (यह संभव नहीं है और क्यों)। –

+0

दिलचस्प, यह काम कर सकता है, लेकिन मुझे अपने इंजन के साथ काम करने के लिए इस समाधान को सामान्यीकृत करने की आवश्यकता होगी। मैं http://www.jeff.wilcox.name/2011/06/updated-ut-mango-bits/ से परीक्षण ढांचे का उपयोग कर रहा हूं, और [असिंक्रोनस] टैग समर्थित नहीं प्रतीत होता है (मुझे एक कंपाइलर मिलता है त्रुटि)। – swinefeaster

+0

@ स्विसफेस्टर - यह वास्तव में ढांचे का हिस्सा है, लेकिन यह 'माइक्रोसॉफ्ट। सिल्वरलाइट। टेस्टिंग' नामस्थान में है। –

1

गलत समस्या का बुरा समाधान क्यों मांगें? यदि आपको एसिंक्रोनस अनुरोधों पर निरंतरता की आवश्यकता है, तो आपको बस कार्य समानांतर लाइब्रेरी का उपयोग करना चाहिए।

आप NuGet: Task Parallel Library for Silverlight पर विंडोज फोन के लिए टीपीएल का एक संस्करण पा सकते हैं।

यह निरंतरता की अनुमति देता है, जो अनिवार्य रूप से आपके धागे को अवरुद्ध करने के समान प्रभाव देगा।

(लाइब्रेरी के निर्माता रॉबर्ट मैकलोस) NuGet एक ऐसी प्रणाली है जो निर्भरताओं का प्रबंधन करना आसान बनाता है। बस http://nuget.org/ पर जाएं, इसे इंस्टॉल करने के लिए लिंक पर क्लिक करें, फिर पैकेज प्रबंधक कंसोल खोलें और "इंस्टॉल-पैकेज सिस्टम। थ्रेडिंग टास्क" टाइप करें, और यह स्वचालित रूप से आपके प्रोजेक्ट के लिए सही संस्करण इंस्टॉल करेगा। मैं वर्तमान में स्रोत उपलब्ध नहीं कर रहा हूं, हालांकि मैं भविष्य में कभी-कभी हो सकता हूं। मुझे मोनो लोगों से जांच करने की ज़रूरत है, क्योंकि कोड ज्यादातर मोनो से आता है।

+0

मुझे स्रोत फ़ाइलों में एक डाउनलोड लिंक नहीं दिख रहा है ...? – swinefeaster

+0

रॉबर्ट ने मेरी पोस्ट में एक संपादन में अपनी टिप्पणी को जोड़ा (क्योंकि वह किसी भी तरह से इसे टिप्पणी के रूप में नहीं लिख सकता था) –

+0

क्या आप एक उदाहरण दिखा सकते हैं कि मैं इस पुस्तकालय का उपयोग कैसे एक वेब पेज की सामग्री को सिंक्रनाइज़ करने के लिए कर सकता हूं और इसकी सामग्री वापस कर सकता हूं एक स्ट्रिंग के रूप में? धन्यवाद – swinefeaster

1

आप ऐसा करने के लिए आरएक्स (लाइब्रेरी के साथ जहाजों) का भी उपयोग कर सकते हैं।

http://dotnet.dzone.com/articles/5-minute-sample-fromasyncpattern

+0

क्या यह वास्तव में एसिंक कॉल से सिंक कॉल करता है? पहली नज़र में ऐसा लगता है कि यह सिंटैक्स के साथ मदद करता है लेकिन इसके नीचे अभी भी async करता है ... – swinefeaster

+0

हाँ, लेकिन टीपीएल के साथ, आरएक्स निरंतरता का उपयोग करता है, जिसका अर्थ है कि आप कोड को निष्पादित कर सकते हैं जब (async) अनुरोध किया जाता है, इसके बजाए धागे को अवरुद्ध करना है। –

+0

ऐसा करता है, यह वास्तव में क्लॉस के जवाब के नीचे एक टिप्पणी होनी चाहिए थी। आप आरएक्स के साथ जो चीजें चाहते हैं, वही कर सकते हैं .. मैं हमेशा एक मतदान और –

2

मैं नहीं यूआई धागा, है जो आप शायद के साथ, कई बार जब फोन करने के लिए तुल्यकालिक कोड पोर्टिंग है कि यह एक है करने के लिए अच्छा होगा देखते हैं अंत करने जा रहे हैं करने के लिए आगे बढ़ सामान की वकालत कर रहा हूँ जबकि GetResponse का सिंक्रोनस संस्करण। लाइब्रेरी के लिए I wrote these extensions methods मैं बनाए रखता हूं कि यह कई प्लेटफ़ॉर्म के साथ संगत है।

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

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