का चयन करें मैं Asp.Net कोर पहचान का उपयोग कर रहा हूं और कुछ कोड को सरल बनाने की कोशिश कर रहा हूं जो उपयोगकर्ताओं की सूची और उनकी भूमिका को व्यूमोडेल में प्रोजेक्ट करता है। यह कोड काम करता है, लेकिन इसे सरल बनाने की कोशिश में मैं त्रुटियों और जिज्ञासा की पागल सर्पिल में गया हूं।async/await का उपयोग करना। Lambda
यहाँ मेरे कार्य कोड है:
var allUsers = _userManager.Users.OrderBy(x => x.FirstName);
var usersViewModel = new List<UsersViewModel>();
foreach (var user in allUsers)
{
var tempVm = new UsersViewModel()
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName,
DisplayName = user.DisplayName,
Email = user.Email,
Enabled = user.Enabled,
Roles = String.Join(", ", await _userManager.GetRolesAsync(user))
};
usersViewModel.Add(tempVm);
}
कोड को आसान बनाने की कोशिश कर रहा में, मैं समझ मैं इस (टूटी हुई कोड) की तरह कुछ कर सकता है:
var usersViewModel = allUsers.Select(user => new UsersViewModel
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName,
DisplayName = user.DisplayName,
Email = user.Email,
Enabled = user.Enabled,
Roles = string.Join(", ", await _userManager.GetRolesAsync(user))
}).ToList();
यह ब्रेक क्योंकि मैं उपयोगकर्ता से पहले लैम्ब्डा अभिव्यक्ति में async कीवर्ड का उपयोग नहीं कर रहा हूं। हालांकि, जब मैं उपयोगकर्ता से पहले async जोड़ने करते हैं, मैं अभी तक एक और त्रुटि का कहना है कि "Async लैम्ब्डा भाव अभिव्यक्ति के पेड़ में परिवर्तित नहीं किया जा सकता है"
मेरा अनुमान है कि GetRolesAsync() प्रणाली टास्क और लौट जाता है मिल उस कार्य के वास्तविक परिणामों की बजाय भूमिकाओं को आवंटित करना। मेरे जीवन के लिए मुझे क्या लगता है कि यह काम नहीं कर रहा है।
मैंने शोध किया है और पिछले दिन कई किस्मत के साथ कई तरीकों का प्रयास किया है।
Is it possible to call an awaitable method in a non async method?
https://blogs.msdn.microsoft.com/pfxteam/2012/04/12/asyncawait-faq/
Calling async method in IEnumerable.Select
How to await a list of tasks asynchronously using LINQ?
how to user async/await inside a lambda
How to use async within a lambda which returns a collection
: यहाँ कुछ है कि मैं को देखा हैंमान्य है, मैं पूरी तरह से समझ नहीं पा रहा हूं कि कैसे async/काम का इंतजार है, तो शायद यह समस्या का हिस्सा है। मेरा foreach कोड काम करता है, लेकिन मैं समझने में सक्षम होना चाहता हूं कि जिस तरह से मैं कोशिश कर रहा हूं उसे कैसे काम करना है। चूंकि मैंने इस पर इतना समय बिताया है, मुझे लगा कि यह एक अच्छा पहला सवाल होगा।
धन्यवाद!
संपादित
मैं मैं क्या मैं लेख मैं एक नकली प्रश्न के रूप में चिह्नित नहीं किया जा करने के लिए इस क्रम में शोध के प्रत्येक मामले में किया था समझाना पड़ेगा लगता है - और मुझे लगता है कि से बचने के लिए वास्तव में कड़ी मेहनत करने की कोशिश की: - /। जबकि सवाल समान लगता है, परिणाम नहीं हैं।
public async Task<ActionResult> Users()
{
var allUsers = _userManager.Users.OrderBy(x => x.FirstName);
var tasks = allUsers.Select(GetUserViewModelAsync).ToList();
return View(await Task.WhenAll(tasks));
}
public async Task<UsersViewModel> GetUserViewModelAsync(ApplicationUser user)
{
return new UsersViewModel
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName,
DisplayName = user.DisplayName,
Email = user.Email,
Enabled = user.Enabled,
Roles = String.Join(", ", await _userManager.GetRolesAsync(user))
};
}
मैं भी करने की कोशिश की तो जैसे AsEnumerable का उपयोग कर: लेख है कि एक जवाब के रूप में चिह्नित किया गया था के मामले में मैं निम्नलिखित कोड की कोशिश की
var usersViewModel = allUsers.AsEnumerable().Select(async user => new UsersViewModel
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName,
DisplayName = user.DisplayName,
Email = user.Email,
Enabled = user.Enabled,
Roles = string.Join(", ", await _userManager.GetRolesAsync(user))
}).ToList();
इन दोनों त्रुटि संदेश का उत्पादन: " अमान्य ऑपरेशन अपवाद: पिछले ऑपरेशन पूर्ण होने से पहले इस संदर्भ पर एक दूसरा ऑपरेशन शुरू हुआ।किसी भी इंस्टेंस सदस्यों को थ्रेड सुरक्षित होने की गारंटी नहीं है। "
इस बिंदु पर ऐसा लगता है कि मेरा मूल ForEach सबसे अच्छा शर्त हो सकता है, लेकिन मैं अभी भी सोच रहा हूं कि ऐसा करने का सही तरीका क्या होगा थे async तरीकों का उपयोग कर यह करने के लिए
संपादित करें 2 - उत्तर के साथ त्सेंग की टिप्पणी के लिए धन्यवाद (और कुछ अन्य अनुसंधान) मैं निम्नलिखित कोड का उपयोग कर काम बातें कर रहा था:।
var userViewModels = allUsers.Result.Select(async user => new UsersViewModel
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName,
DisplayName = user.DisplayName,
Email = user.Email,
Enabled = user.Enabled,
Roles = string.Join(", ", await _userManager.GetRolesAsync(user))
});
var vms = await Task.WhenAll(userViewModels);
return View(vms.ToList());
हालांकि अब मैंने हर किसी को लिया है ध्यान में रखते हुए, मैंने एसक्यूएल प्रोफाइलर के करीब देखना शुरू कर दिया कि यह देखने के लिए कि डीबी वास्तव में कितनी हिट कर रही है - मैट जॉनसन ने उल्लेख किया है, यह बहुत कुछ है (एन + 1)।
तो जब यह मेरे प्रश्न का उत्तर देता है, तो अब मैं क्वेरी को चलाने के तरीके पर पुनर्विचार कर रहा हूं और मुख्य दृश्य में भूमिकाओं को छोड़ सकता हूं और केवल उन्हें प्रत्येक उपयोगकर्ता के रूप में चुन सकता हूं। हालांकि मैंने निश्चित रूप से इस सवाल के माध्यम से बहुत कुछ सीखा है (और जो कुछ मुझे नहीं पता है उससे ज्यादा सीखा है), इसलिए सभी को धन्यवाद।
'मेरा अनुमान है कि GetRolesAsync() विधि कार्य को वापस कर रही है और उस कार्य के वास्तविक परिणामों की बजाय भूमिकाओं को असाइन कर रही है।'- शायद नहीं, क्योंकि 'प्रतीक्षा' कार्य के परिणाम को पकड़ लेगा। – mason
'चयन करें' से पहले 'AsEnumerable' डालने का प्रयास करें ताकि यह EF के लिए अभिव्यक्ति वृक्ष में परिवर्तित करने की कोशिश करने के बजाय LIVq में ऑब्जेक्ट्स में चलाया जा सके या जो भी प्रदाता आप उपयोग करते हैं। – juharr
वर usersViewModels = (इंतजार Task.WhenAll (allUsers.AsEnumerable()। का चयन करें (async उपयोगकर्ता => नई UsersViewModel { आईडी = user.Id, उपयोगकर्ता नाम = user.UserName, प्रथम = user.FirstName, अंतिम नाम = user.LastName, DisplayName = user.DisplayName, ईमेल = user.Email, सक्षम = user.Enabled, भूमिकाओं = string.Join (",", का इंतजार _userManager.GetRolesAsync (उपयोगकर्ता)) })))। सूची बनाने के लिए(); –