मैं हाल ही में सी # 5.0 एसिंक विधियों का उपयोग करना चाहता हूं, हालांकि कुछ विशिष्ट तरीका।क्या सी # 5.0 में एक ही एसिंक विधि हस्ताक्षर का उपयोग करना संभव है और बाद में यह तय करने में सक्षम हो कि इस विधि को कैसे कार्यान्वित किया जाए
public abstract class SomeBaseProvider : ISomeProvider
{
public abstract Task<string> Process(SomeParameters parameters);
}
public class SomeConcreteProvider1 : SomeBaseProvider
{
// in this method I want to minimize any overhead to create/run Task
// NOTE: I remove here async from method signature, because basically I want to run
// method to run in sync!
public override Task<string> Process(SomeParameters parameters) {
string result = "string which I don't need any async code to get";
return Task.Run(() => result);
}
}
public class SomeConcreteProvider2 : SomeBaseProvider
{
// in this method, it's OK for me to use async/await
public async override Task<string> Process(SomeParameters parameters) {
var data = await new WebClient().DownloadDataTaskAsync(urlToRequest);
string result = // ... here we convert data byte[] to string some way
return result;
}
}
अब कैसे मैं async तरीकों का उपयोग करने जा रहा हूँ (आप इस तथ्य मेरे मामले में उपभोक्ता वास्तव में ASP.NET MVC4 एप्लिकेशन ... यह कुछ भी हो सकता है कि उपेक्षा कर सकते हैं):
उदाहरण कोड निम्नलिखित पर विचार करें:
public class SomeAsyncController : AsyncController
{
public async Task<ActionResult> SomethingAsync(string providerId)
{
// we just get here one of providers I define above
var provider = SomeService.GetProvider(providerId);
// we try to execute here Process method in async.
// However we might want to actually do it in sync instead, if
// provider is actually SomeConcreteProvider1 object.
string result = await provider.Process(new SomeParameters(...));
return Content(result);
}
}
आप 2 कार्यान्वयन है देख सकते हैं, हर एक को अलग ढंग से प्रदर्शन करेंगे: एक मैं async में चलाना चाहते हैं और धागे को ब्लॉक नहीं करती (SomeConcreteProvider2), जबकि दूसरे से मैं सिंक में चलाने के लिए सक्षम होना चाहता हूँ और कोई कार्य ऑब्जेक्ट आदि न बनाएं (जो मैं उपरोक्त कोड में कोड करने में विफल रहता हूं, यानी मैं यहाँ नया कार्य बना रहा हूँ!)।
पहले से ही How would I run an async Task<T> method synchronously? जैसे प्रश्न हैं। हालांकि मैं सिंक में कुछ नहीं चलाना चाहता हूं ... अगर मैं कोड समय (यानी रनटाइम से पहले) पर जानता हूं तो मैं किसी भी ओवरहेड से बचना चाहता हूं कि कुछ विधियों के कार्यान्वयन वास्तव में असिंक नहीं होंगे और किसी भी धागे/I का उपयोग करने की आवश्यकता नहीं होगी/ओ पूर्णता बंदरगाह इत्यादि। यदि आप उपरोक्त कोड की जांच करते हैं, तो यह देखने में आसान है कि कुछ कंक्रीटप्रोवाइडर 1 में उस विधि को मूल रूप से कुछ स्ट्रिंग (एचटीएमएल) का निर्माण किया जाएगा, यह उसी निष्पादन थ्रेड पर बहुत तेज़ी से कर सकता है। हालांकि SomeConcreteProvider2 में एक ही विधि को वेब अनुरोध बनाने, वेब प्रतिक्रिया प्राप्त करने और इसे किसी भी प्रक्रिया की आवश्यकता होगी और मैं अनुरोध समय के दौरान पूरे धागे को अवरुद्ध करने से बचने के लिए Async में कम से कम वेब अनुरोध करना चाहता हूं (वास्तव में लंबे समय से छोड़ दिया जा सकता है)।
तो सवाल यह है कि: विधि को निष्पादित करने का तरीका तय करने में सक्षम होने के लिए मेरे कोड (विभिन्न विधि हस्ताक्षर या विभिन्न कार्यान्वयन, या?) को व्यवस्थित करने के लिए कैसे करें और किसी भी संभावित ओवरहेड से बचें जो उदाहरण के लिए कार्य के कारण होता है। Run (.. ।) कुछ कंक्रीटप्रोवाइडर 1। प्रोसेस विधि में?
अद्यतन 1: स्पष्ट समाधान इस तरह के प्रदाताओं में से प्रत्येक के लिए कुछ स्थिर संपत्ति जोड़ने के लिए उदाहरण के लिए के रूप में (कहते हैं 'isAsyncImplementation') और फिर उस संपत्ति की जाँच कैसे तय करने के लिए (मैं उनमें से कुछ सवाल प्रक्रिया के दौरान लगता है), विधि को चलाने के लिए (प्रतीक्षा करने या नियंत्रक कार्रवाई में इंतजार किए बिना) कुछ ओवरहेड भी है: DI यदि संभव हो तो कुछ बेहतर चाहिए: डी
पीएस इस सवाल के लिए सही शीर्षक बनाना वाकई मुश्किल था। अगर कोई इसे ठीक कर सकता है तो खुशी होगी :) धन्यवाद – Evereq
मेरा मानना है कि बिना किसी इंतजार के एसिंक विधि बनाना कार्य कैशिंग के कारण तेज हो सकता है। – SLaks
@SLaks का मतलब है कि मेरा कोड कुछ कंक्रीटप्रोवाइडर 1 में है। कुछ कार्य कैशिंग के कारण प्रोसेस पहले से ही पर्याप्त है? – Evereq