2013-08-08 10 views
7

मेरे पास एक छोटा .NET 4.5 C# ऐप है जो डेटा स्रोत से जानकारी पढ़ता है और फिर इस जानकारी को ऐसी वेबसाइट पर धक्का देता है जो एक साधारण नियंत्रक के साथ .NET 4.5 वेब API साइट है। नियंत्रक डेटा प्राप्त करता है और इसे डेटाबेस में रखता है।.NET HTTPClient Asynchronous Limitations

मेरे लिए निम्नलिखित काम करता है, के रूप में तेजी से और आवेदन लिख सकते हैं पढ़ सकते हैं सब कुछ डीबी में समाप्त होता है:

public static void PostDataToWebApi(MyDataClass tData) 
    { 
     HttpResponseMessage s = null; 

     try 
     { 
      s = client.PostAsJsonAsync("/api/Station/Collector", tData).Result; 
      s.EnsureSuccessStatusCode(); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("ERROR (ClientPost): " + e.ToString()); 
     } 
    } 

निम्नलिखित काम नहीं करता है। यह एक हजार के करीब रिकॉर्ड के बारे में पदों और फिर सभी संदेश के साथ त्रुटि "एक कार्य रद्द कर दिया गया" की संख्या के साथ आता है, लेकिन फिर 10 सेकंड के बाद यह प्रसंस्करण शुरू:

public static async void PostDataToWebApi(MyDataClass tData) 
    { 
     HttpResponseMessage s = null; 

     try 
     { 
      s = await client.PostAsJsonAsync("/api/Station/Collector", tData); 
      s.EnsureSuccessStatusCode(); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("ERROR (ClientPost): " + e.ToString()); 
     } 
    } 

पूर्ण त्रुटि है:

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at IICE_DataCollector_Remote.Program.<PostDataToWebApi>d__7.MoveNext() in e:\Users\TestUser.TEST\Documents\Visual Studio 2012\Projects\Test_App-trunk\TestCollector\Program.cs:line 475 

इसके लिए कोई त्वरित समाधान? जो मैं कह सकता हूं उससे कुछ, थ्रेड, सॉकेट, जो जानता है :-)

किसी भी पॉइंटर्स की सराहना की जाएगी, मुझे यह काम करना अच्छा लगेगा, क्योंकि आप कल्पना कर सकते हैं कि पोस्ट को सिंक्रनाइज़ करना काफी धीमा है असीमित रूप से।

बस यह सुनिश्चित करने के लिए कि यह मेरी मशीन नहीं है, स्थानीय एंटी-वायरस या नेटवर्क मैंने W2k8 R2 सर्वर, विंडोज 7 वर्चुअल अतिथि डेस्कटॉप (ताजा बिल्ड) और विंडोज 8 मशीन पर भी कोशिश की है एक ही परिणाम।

अधिक जानकारी: मैं 500,000 रिकॉर्ड के साथ एक लैन और 100 के एक DefaultConnectionLimit एक छोटे डेटा सेट (10,000 रिकॉर्ड) के संबंध, से आंशिक सफलता लेकिन उत्पादन में, के साथ इस परीक्षण किया है, जब एक दूरस्थ सर्वर से पोस्टिंग इंटरनेट पर (अभी भी कम विलंबता 25ms-50ms) मुझे कोई सफलता नहीं मिली है।

:-)

+0

इस अपवाद के लिए क्या संदेश? –

+0

क्या आप अपने दूसरे संस्करण में 'प्रतीक्षा' नहीं खो रहे हैं? ऐसा लगता है कि इसे संकलित भी नहीं करना चाहिए ... –

+0

@ जोन्स स्केट आप मेरी तरफ से सही हैं, प्रतिलिपि बनाते हैं और पेस्ट करते हैं! इसे सही किया है। – Dominik

उत्तर

8

ठीक है किसी भी मदद के लिए अग्रिम धन्यवाद, मैं इसे अब काम कर रहा है। सबसे बड़ी बात यह है कि सर्वर के लिए क्लाइंट एंड पर सेटिंग्स को सुदृढ़ करना था। यह सेटिंग्स अलग-अलग थीं कि मैं स्थानीय रूप से या इंटरनेट पर परीक्षण चला रहा था या नहीं।

मेरे "PostDataToWebApi" विधि अब इस तरह दिखता है:

public static async void PostDataToWebApi(MyDataClass tData) 
     { 

     await throttler.WaitAsync(); 
     allTasks.Add(Task.Run(async() => 
     { 

      try 
      { 
       var s = await client.PostAsJsonAsync("/api/Station/Collector", tData).ConfigureAwait(false); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("ERROR (ClientPost): " + e.ToString()); 
      } 
      finally 
      { 
       throttler.Release(); 
      } 
     })); 
    } 

मैं है मेरे कंसोल आवेदन के शीर्ष पर घोषित निम्नलिखित:

private static List<Task> allTasks = new List<Task>(); 
    private static SemaphoreSlim throttler; 

मेरी पाश शुरू होता है मैं निम्नलिखित है से पहले, चर के साथ बनाने के लिए बदल यकीन है कि यह सब काम करता है:

ServicePointManager.DefaultConnectionLimit = _DefaultConnections; 
    ServicePointManager.MaxServicePointIdleTime = _MaxIdleTime; 
    ServicePointManager.Expect100Continue = false; 
    ServicePointManager.CheckCertificateRevocationList = false; 

    throttle = new SemaphoreSlim(initialCount: _MaxQueue); 

एक गाइड के रूप में, एक मैं के लिए आधारित लेन-देन nternet मेरे लिए निम्नलिखित काम करता है:

  1. डिफ़ॉल्ट कनेक्शन: 24
  2. अधिकतम निष्क्रिय समय: 400
  3. SemaphoreSlim प्रारंभिक गणना: 50

मेरी लैन परीक्षण के लिए मैं चला सकते हैं दोनों डिफॉल्ट कनेक्शन और शुरुआती गिनती मान बिना किसी समस्या के उच्च होते हैं, मुझे उम्मीद है :-)

आखिरकार, मेरे देखो के बाहर मेरे पास यह सुनिश्चित करने के लिए निम्नलिखित है कि मैं नहीं करता मेरे निष्पादन के अंत में चल रहे किसी भी कार्य को अभी भी मारें:

 await Task.WhenAll(allTasks); 

आशा है कि इससे मदद मिलती है!

+0

आत्म-उत्तर के लिए धन्यवाद! यह counterintuitive लगता है, लेकिन मुझे उदाहरण सेटिंग्स के अनुसार कनेक्शन गिनती से अधिक सेमफोर प्रारंभिक गणना होना महत्वपूर्ण है।अन्यथा थ्रूपुट बहुत कम हो गया था। – stannius

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