से एसिंक विधियों को कॉल करना मैं एक पुस्तकालय को अद्यतन करने की प्रक्रिया में हूं जिसमें एक एपीआई सतह है जिसे .NET 3.5 में बनाया गया था। नतीजतन, सभी विधियां तुल्यकालिक हैं। मैं एपीआई नहीं बदल सकता (यानी, वापसी मूल्यों को कार्य में परिवर्तित करें) क्योंकि इसकी आवश्यकता होगी कि सभी कॉलर्स बदल जाएंगे। इसलिए मुझे एक सिंक्रोनस तरीके से एसिंक विधियों को सर्वश्रेष्ठ तरीके से कॉल करने के तरीके के साथ छोड़ दिया गया है। यह एएसपी.नेट 4, एएसपी.नेट कोर, और .NET/.NET कोर कंसोल अनुप्रयोगों के संदर्भ में है।गैर-एसिंक कोड
मुझे पर्याप्त स्पष्ट नहीं हो सकता है - स्थिति यह है कि मेरे पास मौजूदा कोड है जो एसिंक जागरूक नहीं है, और मैं System.Net.Http और AWS SDK जैसे नए पुस्तकालयों का उपयोग करना चाहता हूं जो केवल async विधियों का समर्थन करते हैं। तो मुझे अंतराल को पुल करने की जरूरत है, और कोड प्राप्त करने में सक्षम होना जिसे सिंक्रनाइज़ कहा जा सकता है लेकिन फिर कहीं और एसिंक विधियों को कॉल कर सकता है।
मैंने बहुत सी पढ़ाई की है, और कई बार यह पूछा गया है और उत्तर दिया गया है।
Calling async method from non async method
Synchronously waiting for an async operation, and why does Wait() freeze the program here
Calling an async method from a synchronous method
How would I run an async Task<T> method synchronously?
Calling async method synchronously
How to call asynchronous method from synchronous method in C#?
समस्या यह है कि अधिकांश उत्तर अलग हैं! मैंने देखा है कि सबसे आम दृष्टिकोण का उपयोग होता है। रिसेट, लेकिन यह deadlock कर सकते हैं। मैंने निम्नलिखित सभी की कोशिश की है, और वे काम करते हैं, लेकिन मुझे यकीन नहीं है कि डेडलॉक्स से बचने के लिए सबसे अच्छा तरीका कौन सा है, अच्छा प्रदर्शन है, और रनटाइम के साथ अच्छी तरह से खेलता है (कार्य शेड्यूलर, कार्य निर्माण विकल्प इत्यादि के सम्मान में))। क्या कोई निश्चित उत्तर है? सबसे अच्छा तरीका क्या है?
private static T taskSyncRunner<T>(Func<Task<T>> task)
{
T result;
// approach 1
result = Task.Run(async() => await task()).ConfigureAwait(false).GetAwaiter().GetResult();
// approach 2
result = Task.Run(task).ConfigureAwait(false).GetAwaiter().GetResult();
// approach 3
result = task().ConfigureAwait(false).GetAwaiter().GetResult();
// approach 4
result = Task.Run(task).Result;
// approach 5
result = Task.Run(task).GetAwaiter().GetResult();
// approach 6
var t = task();
t.RunSynchronously();
result = t.Result;
// approach 7
var t1 = task();
Task.WaitAll(t1);
result = t1.Result;
// approach 8?
return result;
}
उत्तर यह है कि आप ऐसा नहीं करते हैं। आप नई विधियों को जोड़ते हैं जो असीमित हैं और पुरानी कॉलर के लिए पुराने सिंक्रोनस को रखते हैं। –
यह थोड़ा कठोर लगता है, और वास्तव में नए कोड का उपयोग करने की क्षमता को मारता है। उदाहरण के लिए, एडब्ल्यूएस एसडीके के नए संस्करण में गैर-एसिंक विधियां नहीं हैं। कई अन्य तृतीय पक्ष पुस्तकालयों के लिए वही। तो जब तक आप दुनिया को फिर से लिख नहीं लेते, आप इनमें से किसी का भी उपयोग नहीं कर सकते? –
विकल्प 8: शायद [कार्य पूर्णीकरण स्रोत] (https://msdn.microsoft.com/en-us/library/dd449174 (v = vs.110) .aspx) एक विकल्प हो सकता है? – OrdinaryOrange