c# - वेब एपीआई नियंत्रक(.net कोर) में async/प्रतीक्षा या कार्य का उपयोग करना




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

यह अच्छी तरह से काम करता है हालांकि मैं सोच रहा हूं कि कार्यों का उपयोग करना सबसे अच्छा समाधान है या नहीं? Async / प्रतीक्षा का उपयोग एक बेहतर विचार और अधिक स्वीकार्य तरीका होगा?

हाँ बिल्कुल। एएसपी.नेट पर समांतर प्रसंस्करण करना प्रति अनुरोध एकाधिक थ्रेड का उपभोग करता है, जो आपकी स्केलेबिलिटी को गंभीर रूप से प्रभावित कर सकता है। I / O के लिए असीमित प्रक्रिया बहुत बेहतर है।

async उपयोग करने के लिए, सबसे पहले अपनी सेवा के अंदर, अपनी निम्न-स्तरीय कॉल के साथ शुरू करें। यह शायद किसी बिंदु पर एक HTTP कॉल कर रहा है; एसिंक्रोनस HTTP कॉल का उपयोग करने के लिए इसे बदलें (उदाहरण के लिए, HttpClient )। फिर async वहां से स्वाभाविक रूप से बढ़ने दें।

आखिरकार, आप एसिंक्रोनस getdata1Async , getdata2Async , और getdata3Async विधियों के साथ समाप्त हो getdata1Async , getdata2Async समवर्ती रूप से उपभोग किया जा सकता है:

[HttpGet]
public async Task<IActionResult> myControllerAction()
{
  var t1 = service.getdata1Async();
  var t2 = service.getdata2Async();
  var t3 = service.getdata3Async();
  await Task.WhenAll(t1, t2, t3);

  var data = new returnObject
  {
    d1 = await t1,
    d2 = await t2,
    d3 = await t3
  };

  return Ok(data);
}

इस दृष्टिकोण के साथ, जबकि तीन सेवा कॉल प्रगति पर हैं, myControllerAction चार की बजाय शून्य धागे का उपयोग करता है

मेरे पास एक .NET कोर एपीआई है जिसमें एक नियंत्रक है जो लौटने के लिए एक समेकित वस्तु बनाता है। ऑब्जेक्ट जो बनाता है वह डेटा से बना होता है जो एक सेवा वर्ग में 3 विधि कॉल से आता है। ये सभी एक-दूसरे से स्वतंत्र हैं और एक दूसरे से अलगाव में भाग सकते हैं। वर्तमान में मैं इस नियंत्रक के प्रदर्शन को बेहतर बनाने के लिए कार्यों का उपयोग कर रहा हूं। वर्तमान संस्करण इस तरह कुछ दिखता है ...

[HttpGet]
public IActionResult myControllerAction()
{      
    var data1 = new sometype1();
    var data2 = new sometype2();
    var data3 = new List<sometype3>();

    var t1 = new Task(() => { data1 = service.getdata1(); });
    t1.Start();

    var t2 = new Task(() => { data2 = service.getdata2(); });
    t2.Start();

    var t3 = new Task(() => { data3 = service.getdata2(); });
    t3.Start();

    Task.WaitAll(t1, t2, t3);

    var data = new returnObject
    {
         d1 = data1,
         d2 = data2,
         d2 = data3
    };

    return Ok(data);
}

यह अच्छी तरह से काम करता है हालांकि मैं सोच रहा हूं कि कार्यों का उपयोग करना सबसे अच्छा समाधान है या नहीं? Async / प्रतीक्षा का उपयोग एक बेहतर विचार और अधिक स्वीकार्य तरीका होगा?

उदाहरण के लिए नियंत्रक को एसिंक के रूप में चिह्नित किया जाना चाहिए और सेवा कॉल के लिए प्रत्येक कॉल पर एक प्रतीक्षा की जानी चाहिए?


जैसा कि मैं समझता हूं, आप इसे समानांतर में निष्पादित करना चाहते हैं, इसलिए मुझे नहीं लगता कि आपके कोड में कुछ भी गलत है। जैसा कि गेब्रियल ने उल्लेख किया था, आप कार्यों की समाप्ति का इंतजार कर सकते थे।

[HttpGet]
public async IActionResult myControllerAction()
{      
  var data1 = new sometype1();
  var data2 = new sometype2();
  var data3 = new List<sometype3>();

  var t1 = Task.Run(() => { data1 = service.getdata1(); });
  var t2 = Task.Run(() => { data2 = service.getdata2(); });
  var t3 = Task.Run(() => { data3 = service.getdata3(); });

  await Task.WhenAll(t1, t2, t3); // otherwise a thread will be blocked here

  var data = new returnObject
  {
      d1 = data1,
      d2 = data2,
      d2 = data3
  };

 return Ok(data);
}

आप कुछ पंक्तियों को सहेजने के लिए कार्यों के परिणामों का भी उपयोग कर सकते हैं और कोड को "बेहतर" (टिप्पणियां देखें) बना सकते हैं:

[HttpGet]
public async IActionResult myControllerAction()
{      
  var t1 = Task.Run(() => service.getdata1() );
  var t2 = Task.Run(() => service.getdata2() );
  var t3 = Task.Run(() => service.getdata3() );

  await Task.WhenAll(t1, t2, t3); // otherwise a thread will be blocked here

  var data = new returnObject
  {
      d1 = t1.Result,
      d2 = t2.Result,
      d2 = t3.Result
  };

 return Ok(data);
}




asp.net-core