c# - वेबपिया में async का इंतजार करने के लिए सबसे अच्छा अभ्यास




asp.net-web-api asp.net-core (2)

मेरे पास .NET कोर वेब एपीआई है जो सेवा स्तर के रूप में है I सेवा परत में सभी ईएफ कोड हैं

अगर इस कोड के साथ आधार नियंत्रक हैं

protected Task<IActionResult> NewTask(Func<IActionResult> callback)
{
    return Task.Factory.StartNew(() =>
    {
        try
        {
            return callback();
        }
        catch (Exception ex)
        {
            Logger.LogError(ex.ToString());
            throw;
        }
    });
}

नियंत्रक कार्रवाई में मैं ऊपर की विधि में सेवा करने के लिए सभी कॉलों को लपेटता हूं जैसे कि:

[HttpGet("something")]
public async Task<IActionResult> GetSomething(int somethingId)
{
    return await NewTask(() =>
    {
        var result = _somethingService.GetSomething(somethingId);

        if (result != null)
            return Ok(result);
        else
            return NotFound("Role not found");
    });
}

क्या कल यह सही पैटर्न है कि मुझे कार्रवाई में एक से अधिक सेवा कॉल हो सकती हैं या अन्य webservice पर कॉल कर सकते हैं कृपया सलाह दें।


मैं चाहता हूं कि मेरे एपीआई को एसिंक से लाभ उठाना चाहिए। पैटर्न से ऊपर की जरूरत इन जरूरतों को पूरा करेगी

नहीं, यह नहीं है। धागा पूल पर तुल्यकालिक कार्य चलाना आपको तुल्यकालिक और अतुल्यकालिक कोड की कमियां देता है, न तो इसके लाभ के साथ

कुछ सेवा में कुछ क्रूड ऑपरेशन होते हैं जो एंटीफ्रेमवर्क कोर का उपयोग करते हैं

वर्तमान में, आपकी क्रिया विधि वह है जो मैं "नकली असिंक्रोनस" कहता हूं - यह अतुल्यकालिक (जैसे, await का उपयोग करके) लग रहा है, लेकिन वास्तव में यह सिर्फ पृष्ठभूमि थ्रेड पर अवरुद्ध कोड चला रहा है। ASP.NET पर, आप सच्चे एसिंक्रोनिज़ चाहते हैं, जिसका अर्थ है कि आपको सभी तरह से एसिंक होना चाहिए। एएसपी.नेट पर यह क्यों बुरा है, इसके बारे में अधिक जानने के लिए, एएसपी। नेट लेख में async लिए मेरा परिचय का पहला आधा देखें (यह ज्यादातर एएसपी.नेट गैर-कोर से संबंधित है, लेकिन तुल्यकालिक बनाम अतुल्यकालिक अनुरोधों के बारे में बात करने वाला पहला हिस्सा मान्य है सर्वर के किसी भी प्रकार के लिए)

यह वास्तव में अतुल्यकालिक बनाने के लिए, आपको निम्न स्तर से शुरू करना चाहिए - इस स्थिति में, आपके ईएफसीएर कॉल वे सभी एसिंक्रोनि का समर्थन करते हैं इसलिए, await x.FirstOrDefaultAsync() (और आपके सभी बनाता / अद्यतन / हटाए गए आदि के लिए) का await x.FirstOrDefaultAsync() साथ एपीआई कॉलों को x.FirstOrDefault() जैसे x.FirstOrDefault()

फिर async अनुमति दें / वहां से स्वाभाविक रूप से बढ़ने की await करें; कम्पाइलर आपको मार्गदर्शन करेगा I आप अपने somethingService पर अतुल्यकालिक तरीकों से समाप्त हो जाएंगे, जो कि इस तरह से खाया जा सकता है:

[HttpGet("something")]
public async Task<IActionResult> GetSomething(int somethingId)
{
  var result = await _somethingService.GetSomethingAsync(somethingId);
  if (result != null)
    return Ok(result);
  else
    return NotFound("Role not found");
}

ठीक है, सबसे पहले, आपको Task.Factory.StartNew का उपयोग करना बंद करना चाहिए। Task.Factory.StartNew और Task.Factory.StartNew का उपयोग करें। जब आप भारी सीपीयू-बाउंड काम करते हैं तो आप केवल Task.Run पूल थ्रेड पर चलाना चाहते हैं। आपके मामले में आपको वास्तव में उस पर बिल्कुल ज़रूरत नहीं है इसके अलावा आपको यह याद रखना चाहिए कि आपको केवल Task.Run इस्तेमाल करना चाहिए। विधि को कॉल करते समय Task.Run और विधि के क्रियान्वयन में नहीं। आप इसके बारे में अधिक पढ़ सकते हैं।

क्या आप वास्तव में अपने मामले में चाहते हैं कि आपकी सेवा के अंदर अतुल्यकालिक कार्य होना चाहिए (मुझे वाकई यकीन नहीं है कि आपको अपने मामले में एक सेवा की ज़रूरत है) जब आप वास्तव में डेटाबेस को कॉल कर रहे हैं और आप async / await का उपयोग करना चाहते हैं और सिर्फ एक पृष्ठभूमि धागा पर कुछ सामान चलाने के लिए नहीं

असल में आपकी सेवा कुछ इस तरह दिखनी चाहिए (यदि आप सुनिश्चित हैं कि आपको एक सेवा की ज़रूरत है):

class PeopleService
{
    public async Task<Person> GetPersonByIdAsync(int id)
    {
        Person randomPerson = await DataContext.People.FirstOrDefaultAsync(x => x.Id == id);
        return randomPerson;
    }
}

जैसा कि आप देख सकते हैं कि अब आपकी सेवा डेटाबेस को एसिंक कॉल करता है और यह मूल रूप से आपके पैटर्न क्या होना चाहिए। आप इसे अपने सभी कार्यों में जोड़ सकते हैं (जोड़ें / हटाना / आदि ..)

अपनी सेवा अतुल्यकालिक बनाने के बाद आपको आसानी से कार्रवाई में डेटा का उपभोग करने में सक्षम होना चाहिए।

आपके कार्यों को ऐसा कुछ दिखना चाहिए:

[HttpGet("something")]
public async Task<IActionResult> GetPerson(int id)
{
    var result = await PeopleService.GetPersonByIdAsync(id);

    if (result != null)
        return Ok(result);
    else
        return NotFound("Role not found");
}




async-await