2012-05-23 15 views
5

मेरे पास एक बहुत अजीब स्थिति है।एसएसआईएस पैकेज पर यूरी और वेब क्लाइंट कक्षाओं के साथ अजीब व्यवहार

enter image description here

  • टास्क "सूची प्राप्त" एक स्तंभ और यूआरएल की सूची के साथ एक विधानसभा से एक डेटा तालिका को पुन: प्राप्त एक वस्तु चर में भाग जाना चाहिए:

    मैं इस बहुत ही सरल पैकेज है ।

  • "foreach" पाश वस्तु चर के माध्यम से लूप और एक यूआरएल स्ट्रिंग चर
  • "रन" में यूआरएल को लोड करता है, यूआरएल इस कोड (अपने 2005 तो इम वीबी के साथ फंस) के साथ कहता है:

    Dim myURI As New Uri("http://" + Dts.Variables("URL").Value.ToString()) 
    Dim myWebClient As New System.Net.WebClient 
    myWebClient.OpenReadAsync(myURI) 
    

यूआरएल बुलाया जा रहा है आंतरिक है और सिर्फ पैरामीटर को पहचान लेगा और ऑपरेशन जो कुछ समय लगेगा की एक श्रृंखला प्रदर्शन करती है, यही कारण है कि मैं "OpenReadAsync" का इस्तेमाल किया है

मेरी समस्या यह है: यदि मेरे पास चलाने के लिए 4 यूआरएल हैं, तो पैकेज केवल उनमें से 2 चलाता है। लूप 4 गुना हो जाता है, स्क्रिप्ट को 4 बार कहा जाता है (मैं देख सकता हूं कि मैं इसे डीबग करता हूं), लाइन myWebClient.OpenReadAsync(myURI) 4 अलग-अलग मानों के साथ 4 बार निष्पादित की जाती है, लेकिन यूआरएल में केवल 2 कॉल किए जाते हैं।

यदि मैं पैकेज को फिर से चलाता हूं, तो अन्य 2 यूआरएल अब कॉल किए जाते हैं, जो प्रमाण है कि यूआरएल के साथ कुछ भी गलत नहीं है और यदि मैं ब्राउज़र पर मैन्युअल रूप से 4 यूआरएल कॉल करता हूं (उदाहरण के लिए 4 टैब पर) एक के ठीक बाद, वे सभी अपेक्षित परिणाम उत्पन्न करते हैं, जो प्रमाण है कि यूआरएल को पार करने वाले कोड के साथ कुछ भी गलत नहीं है।

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

किसी भी मदद की सराहना की जाएगी। धन्यवाद

+0

क्या होगा यदि आप के लिए स्विच सिंक्रोनस OpenRead विधि का उपयोग कर? – billinkc

+0

हाय बिलिंकक! मुझे दूसरे रन के बाद टाइमआउट मिलता है। यह अजीब है क्योंकि मुझे 4 यूआरएल कुछ सेकंड में चलाना चाहिए, असल में मैं देख सकता हूं (मेरे पास एक लॉग है) कि दूसरा वाला पहला 5 सेकंड बाद चला। और यदि मैं दूसरी बार पैकेज चलाता हूं, तो 2 शेष यूआरएल ठीक चलते हैं, इसलिए निश्चित रूप से कोड को 2 बार – Diego

+0

से अधिक कोड करने के तथ्य के साथ कुछ भी जब भी मैं एसएसआईएस में "अजीब" कोड मुद्दों में भाग लेता हूं, तो मैं कोड को डंप करता हूं एक .NET कंसोल ऐप पर जाएं और देखें कि क्या मैं वहां व्यवहार को पुन: उत्पन्न कर सकता हूं। मुझे लगता है कि आप पहले से ही कोशिश कर चुके हैं, लेकिन यदि आपके पास नहीं है, तो यह देखने के लिए एक जगह हो सकती है क्योंकि आपके बक्षीस के लिए बहुत प्यार नहीं हुआ है। इसके अलावा, आपका पूरा कोड कैसा दिखता है? कोई भी मौका कि सभी 4 यूआरएल बुलाए जा रहे हैं, लेकिन चूंकि वे एसिंक कॉल हैं, तो आप बाद में प्रभावों का पालन नहीं करते हैं? क्या होगा यदि आप लंबे थ्रेड डालते हैं। वहां सो जाओ, अपेक्षित प्रक्रिया अवधि से मेल खाने के लिए कुछ? एसिंक का उद्देश्य हराता है, मुझे पता है लेकिन कुछ प्रकाश – billinkc

उत्तर

4

मेजबान को अधिभारित करने से बचने के लिए सभी ब्राउज़रों को प्रति होस्ट 2 अनुरोधों तक सीमित होने की उम्मीद है। .NET इस नियम का पालन करता है और मेजबान के लिए केवल 2 समवर्ती कनेक्शन की अनुमति देता है। आप या तो एप्लिकेशन की कॉन्फ़िगरेशन फ़ाइल या कोड के माध्यम से संशोधित करके इस सीमा को बदल सकते हैं।

  • कॉन्फ़िगरेशन फ़ाइल में सीमा बदलने के लिए, system.net/connectionManagement तत्व में maxConnection विशेषता बदलें।
  • कोड के माध्यम से सीमा को बदलने के लिए, स्थिर ServicePointManager.DefaultConnectionLimit संपत्ति बदलें।

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

इसके अलावा, OpenReadAsync क्लाइंट को स्ट्रीम खोलता है और यह सुनिश्चित करता है कि यह तब तक खुला रहता है जब तक आप इसे बंद नहीं करते या इसे एकत्र नहीं किया जाता है। किसी कारण के बिना स्ट्रीम खोलने से बचने के लिए आपको DownloadXXXAsync में से एक का उपयोग करना चाहिए।

डाउनलोडस्ट्रिंगएसिंक को कॉल करने और डाउनलोडस्ट्रिंगएसिंकक पूर्ण घटना में क्लाइंट का निपटान करने का एक बेहतर समाधान होगा।

अद्यतन:

ServicePointManager.DefaultConnectionLimit एक स्थिर क्षेत्र जिसका अर्थ है कि इसके दायरे पूरे AppDomain है में संग्रहित है। एसएसआईएस प्रत्येक पैकेज निष्पादन के लिए एक एकल ऐपडोमेन का उपयोग करता है ताकि मूल्य पूरे पैकेज को प्रभावित करेगा।

आप केवल एक ही मेजबान FindServicePoint प्रयोग करने के लिए कनेक्शन सीमा को संशोधित करना चाहते हैं, तो आप मेजबान पते के लिए एक ServicePoint बना सकते हैं और सिर्फ इस पते के लिए सीमा निर्धारित कर सकते हैं:

var myTarget= ServicePointManager.FindServicePoint(new Uri("http://www.google.com")); 
myTarget.ConnectionLimit = 10; 
+0

मैंने जोड़ा <एड्रेस = "*" maxconnection = "5" /> <कनेक्शन प्रबंधन> लेकिन मुझे अभी भी वही व्यवहार मिलता है – Diego

+0

मेरी आखिरी टिप्पणी को अनदेखा करें। मैंने आपके दूसरे लिंक से कोड को 5 स्क्रिप्ट के साथ अपने स्क्रिप्ट कार्य में जोड़ा और यह पूरी तरह से काम करता था। जो मुझे समझ में नहीं आता है वह है: मैंने अपने वेब क्लाइंट ऑब्जेक्ट का कोई संदर्भ नहीं दिया है। इस सेटिंग को "पढ़ा" कैसे गया? क्या यह एक वैश्विक सेटिंग है? बहुत बहुत धन्यवाद – Diego

+0

मूल्य एक स्थिर क्षेत्र में संग्रहीत है जिसका अर्थ है कि यह ऐपडोमेन के लिए वैश्विक है। एसएसआईएस प्रत्येक पैकेज निष्पादन के लिए एक एकल एपडोमेन का उपयोग करता है, इसलिए अन्य निष्पादन को प्रभावित करने वाले परिवर्तन का कोई खतरा नहीं है। एक ही पते के लिए सीमा को बदलने के लिए कोड के साथ उत्तर अपडेट किया गया केवल –

1
  1. प्रत्येक कार्य और उप-कार्य के लिए अपना टाइमआउट बढ़ाने का प्रयास करें।

  2. मुझसे पूछा नहीं गया था, लेकिन मैं एसएसआईएस का उपयोग करने के बजाय इस तरह एक कार्य कठिन कोड दूंगा। एसएसआईएस ईटीएल के लिए बिल्कुल सही है लेकिन ज्यादा नहीं!