कुछ पुराने कोड (6.7.2) से देखते हुए, ऐसा प्रतीत होता है कि MySQL ADO.NET प्रदाता किसी भी async कार्यक्षमता को सही ढंग से लागू नहीं करता है। इसमें TAP पैटर्न और पुरानी शैली Start..., End... async पैटर्न शामिल हैं। उस संस्करण में, ऐसा प्रतीत होता है कि Db* async विधियाँ बिल्कुल भी नहीं लिखी गई हैं; वे .NET में बेस क्लास वाले का उपयोग कर रहे होंगे जो तुल्यकालिक हैं और सभी कुछ इस तरह दिखते हैं:
public virtual Task<int> ExecuteNonQueryAsync(...) {
return Task.FromResult(ExecuteNonQuery(...));
}
(किसी कार्य में इसे लपेटने के अतिरिक्त ओवरहेड के साथ 100% सिंक्रोनस; संदर्भ स्रोत यहां )
यदि आरंभ और अंत संस्करण सही ढंग से लिखे गए थे (वे नहीं हैं) तो इसे कुछ इस तरह लागू किया जा सकता है:
public override Task<int> ExecuteNonQueryAsync(...) {
return Task<int>.Factory.FromAsync(BeginExecuteNonQueryAsync, EndExecuteNonQueryAsync, null);
}
( SqlCommand के लिए उस विधि का संदर्भ स्रोतए> )
ऐसा करना अंतर्निहित सॉकेट के लिए किसी प्रकार के कॉलबैक एपीआई पर निर्भर है, जो अंततः उस पैटर्न से निपटता है जहां कॉलर सॉकेट पर कुछ बाइट भेजता है और फिर एक पंजीकृत विधि को अंतर्निहित नेटवर्क स्टैक से वापस कॉल किया जाता है जब यह तैयार होता है।
हालांकि, MySQL कनेक्टर ऐसा नहीं करता है (यह उस विधि को पहले स्थान पर ओवरराइड नहीं करता है, लेकिन अगर ऐसा होता है, तो प्रासंगिक प्रारंभ और समाप्ति विधियां कुछ अंतर्निहित सॉकेट एपीआई पर एसिंक नहीं होती हैं)। mysql कनेक्टर क्या करता है इसके बजाय वर्तमान कनेक्शन इंस्टेंस पर एक आंतरिक विधि के लिए एक प्रतिनिधि बना रहा है और इसे एक अलग थ्रेड पर समकालिक रूप से आमंत्रित करता है। आप इस बीच उदाहरण के लिए उसी कनेक्शन पर दूसरी कमांड निष्पादित नहीं कर सकते, कुछ इस तरह:
private static void Main() {
var sw = new Stopwatch();
sw.Start();
Task.WaitAll(
GetDelayCommand().ExecuteNonQueryAsync(),
GetDelayCommand().ExecuteNonQueryAsync(),
GetDelayCommand().ExecuteNonQueryAsync(),
GetDelayCommand().ExecuteNonQueryAsync(),
GetDelayCommand().ExecuteNonQueryAsync(),
GetDelayCommand().ExecuteNonQueryAsync(),
GetDelayCommand().ExecuteNonQueryAsync(),
GetDelayCommand().ExecuteNonQueryAsync(),
GetDelayCommand().ExecuteNonQueryAsync(),
GetDelayCommand().ExecuteNonQueryAsync(),
GetDelayCommand().ExecuteNonQueryAsync(),
GetDelayCommand().ExecuteNonQueryAsync());
sw.Stop();
Console.WriteLine(sw.Elapsed.Seconds);
}
private static DbCommand GetDelayCommand() {
var connection = new MySqlConnection (...);
connection.Open();
var cmd = connection.CreateCommand();
cmd.CommandText = "SLEEP(5)";
cmd.CommandType = CommandType.Text;
return cmd;
}
(यह मानते हुए कि आप कनेक्शन पूलिंग कर रहे हैं और कार्यों की संख्या अधिकतम पूल आकार से अधिक है; यदि एसिंक ने काम किया है तो इस कोड को संख्या के बजाय पूल में कनेक्शन की संख्या के आधार पर एक संख्या मिलेगी और दोनों की संख्या के आधार पर थ्रेड जो एक साथ चल सकते हैं)
ऐसा इसलिए है क्योंकि कोड में एक ड्राइवर को लॉक करें (वास्तविक चीज़ जो नेटवर्क इंटर्नल का प्रबंधन करती है; *)। और अगर ऐसा नहीं होता (और आंतरिक अन्यथा थ्रेड सुरक्षित थे और कनेक्शन पूल को प्रबंधित करने के लिए किसी अन्य तरीके का उपयोग किया गया था) यह अंतर्निहित नेटवर्क स्ट्रीम पर ब्लॉकिंग कॉल निष्पादित करता रहता है .
तो हाँ, इस कोडबेस के लिए कोई एसिंक समर्थन दृष्टि में नहीं है। मैं एक नए ड्राइवर को देख सकता था अगर कोई मुझे कोड पर इंगित कर सकता है, लेकिन मुझे आंतरिक NetworkStream
पर संदेह है आधारित वस्तुएं काफी अलग नहीं दिखती हैं और एसिंक कोड भी बहुत अलग नहीं दिख रहा है। एक async
सपोर्टिंग ड्राइवर के पास अधिकांश इंटर्नल होंगे जो इसे करने के एसिंक्रोनस तरीके पर निर्भर करते हैं और सिंक्रोनस कोड के लिए सिंक्रोनस रैपर होते हैं; वैकल्पिक रूप से यह SqlClient
की तरह बहुत अधिक दिखाई देगा संदर्भ स्रोत और कुछ कार्य
. पर निर्भर करते हैं सिंक्रोनाइज़ या एसिंक्स चलाने के बीच के अंतर को दूर करने के लिए लाइब्रेरी को रैप करना।
* ड्राइवर को लॉक करने का मतलब यह नहीं है कि यह संभवतः गैर-अवरुद्ध आईओ का उपयोग नहीं कर सकता है, बस विधि को लॉक स्टेटमेंट के साथ नहीं लिखा जा सकता है और गैर-अवरुद्ध प्रारंभ/समाप्ति IAsyncResult
कोड जो TAP पैटर्न से पहले लिखा जा सकता था।
संपादित करें:6.9.8 डाउनलोड किया गया; जैसा कि संदेह है कि कोई कार्यशील एसिंक कोड नहीं है (गैर-अवरुद्ध आईओ संचालन); यहां एक बग फाइल किया गया है:https://bugs.mysql.com/bug. php?id=70111
अपडेट 6 जुलाई 2016:गिटहब पर दिलचस्प परियोजना जो अंततः इसे https://github.com/ पर संबोधित कर सकती है। mysql-net/MySqlConnector (शायद अधिक योगदानकर्ताओं का उपयोग कर सकता है जिनकी सफलता में हिस्सेदारी है [मैं अब MySQL के साथ किसी भी चीज़ पर काम नहीं कर रहा हूं])।