HttpContext.Current शून्य का इंतजार क्यों है?


89

मेरे पास निम्नलिखित परीक्षण WebAPI कोड है, मैं उत्पादन में WebAPI का उपयोग नहीं करता हूं, लेकिन मैंने इस प्रश्न पर चर्चा के कारण इसे बनाया है: WebAPI Async प्रश्न

वैसे भी, यहाँ अपमानजनक WebAPI विधि है:

public async Task<string> Get(int id)
{
    var x = HttpContext.Current;
    if (x == null)
    {
        // not thrown
        throw new ArgumentException("HttpContext.Current is null");
    }

    await Task.Run(() => { Task.Delay(500); id = 3; });

    x = HttpContext.Current;
    if (x == null)
    {
        // thrown
        throw new ArgumentException("HttpContext.Current is null");
    }

    return "value";
}

मुझे यह विश्वास था कि दूसरा अपवाद अपेक्षित है क्योंकि जब awaitपूरा हो जाएगा, तो यह संभवतः एक अलग थ्रेड पर होगा जहां HttpContext.Currentथ्रेड-स्टैटिक वेरिएबल अब उचित मूल्य पर हल नहीं करेगा। अब, तुल्यकालन के संदर्भ के आधार पर, यह वास्तव में प्रतीक्षा के बाद उसी धागे पर वापस जाने के लिए मजबूर हो सकता है लेकिन मैं अपने परीक्षण में कुछ भी नहीं कर रहा हूं। यह सिर्फ एक सादा, अनुभवहीन उपयोग है await

एक अन्य प्रश्न में टिप्पणियों में मुझे बताया गया कि HttpContext.Currentप्रतीक्षा के बाद हल करना चाहिए। इस सवाल पर एक और टिप्पणी भी है जो इसी बात का संकेत दे रही है। तो क्या सच है? क्या इसे हल करना चाहिए? मुझे लगता है कि नहीं, लेकिन मैं इस पर एक आधिकारिक जवाब चाहता हूं asyncऔर awaitयह पर्याप्त है कि मुझे कुछ भी निश्चित नहीं मिल सकता है।

टीएल; डीआर: एक के बाद HttpContext.Currentसंभावित है ?nullawait


3
आपका प्रश्न स्पष्ट नहीं है - आपने कहा है कि आपको क्या होने की उम्मीद थी, और टिप्पणियों से संकेत मिलता है कि यही हो रहा है ... तो क्या आपको भ्रमित कर रहा है?
जॉन स्कीट

@ user2674389, यह भ्रामक है। यह AspNetSynchronizationContextध्यान रखता है HttpContext, नहीं await। अधिक, awaitवेब API निष्पादन मॉडल के लिए एक अलग थ्रेड पर मई (और सबसे अधिक संभावना है) के लिए निरंतर कॉलबैक होगा।
noseratio


1
@JoepBeusenberg अलग-अलग असेंबली बनाना जो केवल तब काम करते हैं जब उन्हें एक असेंबली से बुलाया जाता है जो एक विशेष वेब स्टैक के HTTP अनुरोध के संदर्भ में निष्पादित हो रहा है, ऐसा लगता है कि यह परीक्षण, रखरखाव और एक चुनौती का पुन: उपयोग कर सकता है।
डारेल मिलर

1
@DarrelMiller इसके विपरीत है। मैंने व्यावसायिक तर्क को वास्तविक वेब प्रोजेक्ट से अलग कर दिया है। निर्भरता इंजेक्शन का उपयोग करके मैं व्यावसायिक तर्क के शीर्ष पर एक वेबैपी-जागरूक पुस्तकालय जोड़ सकता हूं। लेकिन यह पुस्तकालय तब टूटता है जब व्यापार तर्क .ConfigureAwait(false)लाइन के नीचे कहीं किया जाता है। कोई भी अनुरोध या नियंत्रक स्पष्ट रूप से व्यावसायिक परत के माध्यम से नहीं दिया गया है, क्योंकि वह वेब-जागरूक नहीं है। यह एक लॉगिंग मॉड्यूल के लिए उदाहरण के लिए उपयोगी है जो अनुरोध विवरण को इंजेक्ट कर सकता है जब व्यापार तर्क एक सामान्य लिखता है TraceInformation
जोएप ब्यूसेंबर्ग

जवाबों:


148

कृपया सुनिश्चित करें कि आप ASP.NET 4.5 अनुप्रयोग लिख रहे हैं , और 4.5 लक्ष्य कर रहे हैं । asyncऔर awaitASP.NET पर अपरिभाषित व्यवहार किया है जब तक आप 4.5 पर नहीं चल रहे हैं और नए "कार्य-अनुकूल" सिंक्रनाइज़ेशन संदर्भ का उपयोग कर रहे हैं।

विशेष रूप से, इसका मतलब है कि आपको या तो:

  • httpRuntime.targetFrameworkकरने के लिए सेट 4.5, या
  • अपने में appSettings, सेट aspnet:UseTaskFriendlySynchronizationContextपर true

अधिक जानकारी यहाँ उपलब्ध है


2
मैंने अभी एक नया ASP.NET 4.5 WebAPI प्रोजेक्ट बनाया, अपने कोड को कॉपी / पेस्ट किया, और एक परीक्षण किया। इसने मेरे लिए पूरी तरह से काम किया (न तो कोई अपवाद दिया गया)। कृपया पुनः जांचें कि आप 4.5 पर चल रहे हैं और लक्ष्य कर रहे हैं ।
स्टीफन क्लीयर

3
मेरे पास टारगेट फ्रेमवर्क है: .NET फ्रेमवर्क 4.5 सेट। मुझे नहीं पता कि आपको क्या बताना है, यह निश्चित रूप से मेरे स्थानीय मशीन पर शून्य है।
welegan

24
<httpRuntime targetFramework="4.5" />क्या यह स्पष्ट करने के लिए हल है, धन्यवाद है।
welegan

1
@ विंस: 4.5.1 ठीक काम करना चाहिए। मुझे यकीन नहीं है कि आपको targetFramework4.5.1 या 4.5 पर सेट करना चाहिए , लेकिन 4.5.1 पर async को ठीक काम करना चाहिए।
स्टीफन क्लीयर

1
क्या होगा अगर आपने अपना खुद का प्रबंधित हैंडलर लिखा हो? मैं वेब में इन वस्तुओं को जोड़ने के बाद भी HttpContext.Current = null के साथ आता रहता हूं।
ब्रेन २००

28

जैसा कि @StephenCleary ने सही ढंग से बताया, आपको अपने web.config में इसकी आवश्यकता है:

<httpRuntime targetFramework="4.5" />

जब मैं पहली बार यह समस्या निवारण कर रहा था, तो मैंने उपरोक्त के लिए एक समाधान-विस्तृत खोज की, यह पुष्टि की कि यह मेरी सभी वेब परियोजनाओं में मौजूद थी और इसे अपराधी के रूप में जल्दी से खारिज कर दिया। आखिरकार यह मेरे लिए उन खोज परिणामों को पूरे संदर्भ में देखने के लिए हुआ:

<!--
  For a description of web.config changes for .NET 4.5 see http://go.microsoft.com/fwlink/?LinkId=235367.

  The following attributes can be set on the <httpRuntime> tag.
    <system.Web>
      <httpRuntime targetFramework="4.5" />
    </system.Web>
-->

रवींद्र।

पाठ: यदि आप किसी वेब प्रोजेक्ट को 4.5 में अपग्रेड करते हैं, तब भी आपको उस सेटिंग को मैन्युअल रूप से प्राप्त करना होगा।


22
एक और गोचर यह अलग है <संकलन लक्ष्य से काम करता है "4.5" />
एंड्रयू

3

क्या मेरा परीक्षण त्रुटिपूर्ण है, या कोई वेब है। मैं जिस तत्व को याद कर रहा हूँ, वह यहाँ है जो HttpContext.Current संकल्प को एक प्रतीक्षा के बाद सही ढंग से कर देगा?

आपका परीक्षण त्रुटिपूर्ण नहीं है और HttpContext.Current प्रतीक्षा के बाद अशक्त नहीं होना चाहिए क्योंकि ASP.NET वेब एपीआई में जब आप प्रतीक्षा करते हैं, तो यह सुनिश्चित करेगा कि इस प्रतीक्षा के बाद का कोड सही HttpContext पास है जो प्रतीक्षा से पहले मौजूद था।


क्या आप वेबएपीआई के लिए उसी निरंतरता के बारे में निश्चित हैं? मैंने उस मामले से निपटा जहां यह एक अलग धागा था।
noseratio

4
ASP.NET किसी भी थ्रेड पूल थ्रेड पर फिर से शुरू होगा, लेकिन सही अनुरोध संदर्भ के साथ।
स्टीफन क्लीयर

2
हां, आप सही हैं, थ्रेड समान नहीं हो सकता है, लेकिन HttpContext.Current प्रतीक्षा के पहले जैसा होगा। मैंने अपना प्रश्न अपडेट कर दिया है।
डारिन दिमित्रोव

4
HttpContext.Current मेरे कोड में प्रतीक्षा के बाद शून्य है, और मैं .net 4.6.1 को लक्षित कर रहा हूं।
२३:३१ पर त्रिकोको

1
मेरे लिए HttpContext.Current एक प्रतीक्षा समारोह से पहले अशक्त है
JobaDiniz

2

मैं इस मुद्दे पर हाल ही में भाग गया। जैसा कि स्टीफन ने स्पष्ट रूप से बताया कि लक्ष्य रूपरेखा इस मुद्दे को उत्पन्न नहीं कर सकती है।

मेरे मामले में, हमारे वेब एपीआई को 4.6.2 संस्करण में माइग्रेट किया गया था, लेकिन वेब कॉन्फ़िगरेशन में रनटाइम लक्ष्य फ्रेमवर्क कभी निर्दिष्ट नहीं किया गया था, इसलिए मूल रूप से यह <system.web> टैग के अंदर गायब था:

यदि आपको अपने द्वारा चलाए जा रहे फ्रेमवर्क संस्करण के बारे में संदेह है, तो इससे मदद मिल सकती है: अपने वेब एपीआई तरीकों में से किसी पर निम्न पंक्ति जोड़ें और यह सत्यापित करने के लिए एक ब्रेकपॉइंट सेट करें कि वर्तमान में रनटाइम पर किस प्रकार लोड किया गया है और यह सत्यापित करें कि यह एक विरासत कार्यान्वयन नहीं है:

आपको यह देखना चाहिए (AspNetSynchronizationContext):

यहाँ छवि विवरण दर्ज करें

LegazyAspNetSynchronizationContext के बजाय (जो मैंने लक्ष्य रूपरेखा को जोड़ने से पहले देखा था):

यहाँ छवि विवरण दर्ज करें

यदि आप स्रोत कोड ( https://referencesource.microsoft.com/#system.web/LegacyAspNetSynchronizationContext.cs ) पर जाते हैं, तो आप देखेंगे कि इस इंटरफ़ेस के लिगेसी कार्यान्वयन में अतुल्यकालिक समर्थन का अभाव है।

यहाँ छवि विवरण दर्ज करें

मैंने इस मुद्दे के स्रोत को खोजने में बहुत समय बिताया और स्टीफन की प्रतिक्रिया से बहुत मदद मिली। आशा है कि यह उत्तर समस्या के बारे में कुछ और जानकारी प्रदान करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.