मैं एक परियोजना का निर्माण कर रहा हूं और एसिंक का उपयोग कर रहा हूं और विधियों का इंतजार कर रहा हूं। हर कोई कहता है कि एसिंक आवेदन ग्राउंड अप से बनाया गया है, तो क्या आपके पास वास्तव में कोई सिंक विधियां होनी चाहिए? क्या आपको सभी कार्य एक कार्य वापस करना चाहिए ताकि आप असीमित रूप से उपयोग कर सकें?"बहुत ज्यादा" async कब और इंतजार कर रहा है? क्या सभी विधियां कार्य वापस करनी चाहिए?
चलिए एक साधारण उदाहरण लेते हैं, जहां मैं संग्रह में डेटा लोड करने के लिए एसक्यूएल का उपयोग कर रहा हूं, यहां कुछ कोड है।
इस कोड को लोड ExecuteQueryAsync
विधि, विधि GetQuery
एसक्यूएल निर्माण करती है, लेकिन GetTableColumns
कॉलिंग का उपयोग करके एक मेज से डेटा। एक बार जब SQL उत्पन्न होता है और निष्पादित हो जाता है, तो मैं संग्रह के माध्यम से लूप करता हूं और GetDataFromReader
पर कॉल करके प्रत्येक ऑब्जेक्ट को पॉप्युलेट करता हूं।
क्या मेरे गैर एसिंक विधियों को एसिंक होना चाहिए? क्या मैं प्रोग्रामिंग के सिंक-तरीके के बारे में सोच रहा हूं और कुछ खो रहा हूं?
public async Task<ICollection<MyObject>> ExecuteQueryAsync(Module module, List<SqlParameter> parameters)
{
var result = new Collection<MyObject>();
var query = GetQuery(module);
using (var conn = new SqlConnection(_context.Database.Connection.ConnectionString))
{
await conn.OpenAsync();
using (var cmd = new SqlCommand(query, conn))
{
if (parameters != null)
cmd.Parameters.AddRange(parameters.ToArray());
using (var dr = await cmd.ExecuteReaderAsync())
{
while (await dr.ReadAsync())
{
result.Add(GetDataFromReader(module, dr));
}
}
}
}
return result;
}
public string GetQuery(Module module)
{
return "SELECT " + string.Join(",", GetTableColumns(module).ToArray()) + " FROM [TableA] ";
}
public List<string> GetTableColumns(Module module)
{
var columnNames = new List<string>();
// get all list fields for the module
var fields = (from a in module.Groups.SelectMany(a => a.Fields) select a).ToList();
foreach (var field in fields)
{
if (field.Type == FieldType.List) {
string query = "STUFF(";
query += "(SELECT ';' + [Value] FROM [TableB] FOR XML PATH(''))";
query += ", 1, 1, '') AS [" + field.ColumnName + "]";
columnNames.Add(query);
} else {
columnNames.Add("[" + field.ColumnName + "]");
}
}
return columnNames;
}
public MyObject GetDataFromReader(Module module, IDataReader dataReader)
{
var entity = new MyObject();
for (var i = 0; i < dataReader.FieldCount; i++)
{
object value = null;
var fieldName = dataReader.GetName(i);
if (!dataReader.IsDBNull(i))
{
value = dataReader.GetValue(i);
}
entity[fieldName] = value;
}
return entity;
}
यहां कोई निश्चित अंतिम उत्तर नहीं है, यह सब निर्भर करता है। मुझसे छोटी राय; यदि कोई विधि किसी भी एसिंक्रोनस का उपयोग स्वयं नहीं करती है, तो यह स्वयं कुछ पद्धति को फिट करने के लिए एसिंक नहीं होना चाहिए। –
बस एक मामूली नोट। मुझे कॉलस्टैक और संबंधित टूल्स का उपयोग डीबग करने के लिए करना पसंद है, और मैं इसके लिए आपको नफरत करता हूं। Async/Await काफी जटिल वास्तविक कोड पर आसान वाक्यविन्यास है, जो आपको किसी बिंदु पर काट सकता है। –
आपने "async सभी तरह से" के विचार को गलत समझा - यह आपके पूरे async * कॉल पदानुक्रम * async होने के बारे में है। यही है, अगर आप एसिंक्रोनस विधि को कॉल करते हैं, तो आपको स्वयं एसिंक होना चाहिए, और आपके कॉलर और उसके कॉलर इत्यादि भी चाहिए। लेकिन 'string.JoinAsync' या ऐसा कुछ कोड करने का कोई कारण नहीं है - असल में, यह काफी काउंटर- उत्पादक। यदि आप सिंक्रोनस विधियों को केवल कॉल कर रहे हैं, तो आपको * एसिंक नहीं होना चाहिए - यह सिर्फ भ्रामक है। – Luaan