2013-02-21 12 views
6

मेरे पास एक एएसपी.नेट वेब एपीआई नियंत्रक है जो मेरे पास सोचा होगा असीमित रूप से संचालित होगा। नियंत्रक को पहले अनुरोध के लिए 20 सेकंड सोने के लिए डिज़ाइन किया गया है, लेकिन तुरंत बाद के अनुरोधों की सेवा करें।मेरा एसिंक एएसपी.NET वेब एपीआई नियंत्रक मुख्य धागा को अवरुद्ध क्यों कर रहा है?

  1. बढ़ाएं अनुरोध 1.
  2. बढ़ाएं अनुरोध 2.
  3. बढ़ाएं अनुरोध 3.
  4. अनुरोध 2 रिटर्न: तो मेरी प्रत्याशित समय की तरह कुछ होगा।
  5. अनुरोध 3 रिटर्न।
  6. प्रतीक्षा करें ~ 20 सेकंड।
  7. अनुरोध 1 रिटर्न।

इसके बजाय, कोई अनुरोध 1 तक समाप्त होने तक अनुरोध वापस आ गया है।

मैं पुष्टि कर सकता हूं (डीबग आउटपुट के आधार पर), कि प्रवेश थ्रेड और नींद थ्रेड आईडी अलग हैं। नींद को एक अलग थ्रेड पर मजबूर करने के लिए मैंने जानबूझकर TaskCreationOptions.LongRunning का उपयोग किया है, लेकिन फिर भी एप्लिकेशन नींद समाप्त होने तक किसी भी नए अनुरोध की सेवा करने से इंकार कर देता है।

क्या मुझे एसिंक वेब एपीआई नियंत्रक वास्तव में कैसे काम करते हैं, इस बारे में कुछ मौलिक याद आ रही है?


public class ValuesController : ApiController 
{ 
    private static bool _firstTime = true; 

    public async Task<string> Get() 
    { 
     Debug.WriteLine("Entry thread id: {0}. Sync: {1}", 
      Thread.CurrentThread.ManagedThreadId, 
      SynchronizationContext.Current); 
     await LongWaitAsync(); 
     return "FOOBAR"; 
    } 

    private Task LongWaitAsync() 
    { 
     return Task.Factory.StartNew(() => 
      { 
       if (_firstTime) 
       { 
        _firstTime = false; 
        Debug.WriteLine("Sleepy thread id: {0}. Sync: {1}", 
         Thread.CurrentThread.ManagedThreadId, 
         SynchronizationContext.Current); 
        Thread.Sleep(20000); 
        Debug.WriteLine("Finished sleeping"); 
       } 
      }, 
      CancellationToken.None, 
      TaskCreationOptions.LongRunning, 
      TaskScheduler.Default); 
    } 
} 
+0

पहले चरण के रूप में, मैं यह सुनिश्चित करने के लिए '_firstTime' को' अस्थिर 'के रूप में चिह्नित करता हूं, यह सुनिश्चित करने के लिए कि अलग-अलग धागे इसे लगातार बदलते देख सकें। –

+0

होस्ट करने के लिए आप किस वेब सर्वर का उपयोग कर रहे हैं? –

+0

'फर्स्टटाइम' को 'अस्थिर' के रूप में चिह्नित करने से कोई फर्क नहीं पड़ता। मैंने विन 7 प्रो पर आईआईएस एक्सप्रेस 8.0 और आईआईएस 7.5 में होस्टिंग की कोशिश की है। – Snixtor

उत्तर

12

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

क्लाइंट कार्यान्वयन से अलग करने के लिए, मैंने निम्नलिखित क्लाइंट को एक साथ रखा है।

class Program 
{ 
    static void Main(string[] args) 
    { 
     var t1 = Task.Run(() => FetchData(1)); 
     var t2 = Task.Run(() => FetchData(2)); 
     var t3 = Task.Run(() => FetchData(3)); 

     var index = Task.WaitAny(t1, t2, t3); 
     Console.WriteLine("Task {0} finished first", index + 1); 

     Task.WaitAll(t1, t2, t3); 
     Console.WriteLine("All tasks have finished"); 

     Console.WriteLine("Press any key"); 
     Console.ReadKey(true); 
    } 

    static void FetchData(int clientNumber) 
    { 
     var client = new WebClient(); 
     string data = client.DownloadString("http://localhost:61852/api/values"); 
     Console.WriteLine("Client {0} got data: {1}", clientNumber, data); 
    } 
} 

यह उत्पादन चला जाता है: "foobar"

  • कार्य 2 समाप्त पहली
  • :
  • ग्राहक 3 डेटा मिला (स्टार्टअप के मिलीसेकेंड के अंदर) के "foobar":

    1. ग्राहक 2 डेटा मिला "foobar"
    2. सभी टी:
    3. (लंबी यहीं रुको)
    4. ग्राहक 1 डेटा मिला
  • +0

    सोचा था कि मैं पागल हो रहा था। प्रकाशन के लिए धन्यवाद! – NovaJoe

    0

    समाप्त कर दिया है पूछता है मेरे मामले में यहां निर्गम (यह 5 से 10 के लिए एक और धागा करने के लिए स्विच) है:

    Entry thread id: 5. Sync: System.Web.LegacyAspNetSynchronizationContext 
    Sleepy thread id: 10. Sync: 
    Finished sleeping 
    The thread '<No Name>' (0x2c84) has exited with code 0 (0x0). 
    Entry thread id: 7. Sync: System.Web.LegacyAspNetSynchronizationContext 
    The thread '<No Name>' (0x1818) has exited with code 0 (0x0). 
    Entry thread id: 5. Sync: System.Web.LegacyAspNetSynchronizationContext 
    The thread '<No Name>' (0xd4c) has exited with code 0 (0x0). 
    The thread '<No Name>' (0x2c30) has exited with code 0 (0x0). 
    

    यह पर्यावरण और मशीन चल (सिंगल कोर) के कारण हो सकता है कि रनटाइम यह तय करता है कि इसे कैसे चलाया जाए।

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