সমস্যাটি দেখে মনে হচ্ছে আপনি সত্তা ফ্রেমওয়ার্কের সাথে কীভাবে async / কাজের প্রতীক্ষা করছেন তা ভুল বুঝেছেন।
সত্তা ফ্রেমওয়ার্ক সম্পর্কে
সুতরাং, আসুন এই কোডটি দেখুন:
public IQueryable<URL> GetAllUrls()
{
return context.Urls.AsQueryable();
}
এবং এর ব্যবহারের উদাহরণ:
repo.GetAllUrls().Where(u => <condition>).Take(10).ToList()
সেখানে কি হয়?
- আমরা
IQueryableব্যবহার করে অবজেক্ট (এখনও ডাটাবেস অ্যাক্সেস না) পাচ্ছিrepo.GetAllUrls()
- আমরা একটি নতুন তৈরি
IQueryableনির্দিষ্ট শর্ত ব্যবহার করে অবজেক্ট.Where(u => <condition>
- আমরা
IQueryableনির্দিষ্ট পেজিং সীমা ব্যবহার করে একটি নতুন অবজেক্ট তৈরি করি.Take(10)
- আমরা ডাটাবেস ব্যবহার করে ফলাফল পুনরুদ্ধার
.ToList()। আমাদের IQueryableঅবজেক্টটি স্কয়ারে (যেমন select top 10 * from Urls where <condition>) সংকলিত হয় । এবং ডাটাবেস সূচীগুলি ব্যবহার করতে পারে, এসকিউএল সার্ভার আপনাকে আপনার ডাটাবেস থেকে কেবলমাত্র 10 টি বস্তু প্রেরণ করবে (ডাটাবেসে থাকা সমস্ত বিলিয়ন ইউআরএল নয়)
ঠিক আছে, আসুন প্রথম কোডটি দেখুন:
public async Task<IQueryable<URL>> GetAllUrlsAsync()
{
var urls = await context.Urls.ToListAsync();
return urls.AsQueryable();
}
ব্যবহারের একই উদাহরণ সহ আমরা পেয়েছি:
- আমরা আপনার ডাটাবেসে সঞ্চিত সমস্ত বিলিয়ন ইউআরএল মেমরিতে লোড করছি
await context.Urls.ToListAsync();।
- আমরা স্মৃতি ওভারফ্লো পেয়েছি। আপনার সার্ভারকে মেরে ফেলার সঠিক উপায়
সম্পর্কে async / প্রতীক্ষা
কেন async / অপেক্ষার ব্যবহার পছন্দ? আসুন এই কোডটি দেখুন:
var stuff1 = repo.GetStuff1ForUser(userId);
var stuff2 = repo.GetStuff2ForUser(userId);
return View(new Model(stuff1, stuff2));
এখানে কি হয়?
- লাইন 1 এ শুরু
var stuff1 = ...
- আমরা স্কয়ার সার্ভারে অনুরোধটি প্রেরণ করি যা আমরা কিছু স্টাফ 1 পেতে চাই
userId
- আমরা অপেক্ষা করি (বর্তমান থ্রেড অবরুদ্ধ)
- আমরা অপেক্ষা করি (বর্তমান থ্রেড অবরুদ্ধ)
- .....
- SQL সার্ভার আমাদের প্রতিক্রিয়া প্রেরণ
- আমরা লাইন 2 এ চলেছি
var stuff2 = ...
- আমরা স্কিএল সার্ভারে অনুরোধটি প্রেরণ করি যা আমরা কিছু স্টাফ 2 পেতে চাই
userId
- আমরা অপেক্ষা করি (বর্তমান থ্রেড অবরুদ্ধ)
- এবং আবার
- .....
- SQL সার্ভার আমাদের প্রতিক্রিয়া প্রেরণ
- আমরা ভিউ রেন্ডার করি
সুতরাং আসুন এটির একটি অ্যাসিঙ্ক সংস্করণটি দেখুন:
var stuff1Task = repo.GetStuff1ForUserAsync(userId);
var stuff2Task = repo.GetStuff2ForUserAsync(userId);
await Task.WhenAll(stuff1Task, stuff2Task);
return View(new Model(stuff1Task.Result, stuff2Task.Result));
এখানে কি হয়?
- স্টাফ 1 (লাইন 1) পাওয়ার জন্য আমরা এসকিএল সার্ভারে অনুরোধ পাঠাব
- স্টাফ 2 (লাইন 2) পাওয়ার জন্য আমরা এসকিএল সার্ভারে অনুরোধটি প্রেরণ করি
- আমরা স্কিএল সার্ভারের প্রতিক্রিয়াগুলির জন্য অপেক্ষা করি, তবে বর্তমান থ্রেডটি অবরুদ্ধ নয়, তিনি অন্য ব্যবহারকারীদের কাছ থেকে প্রশ্নগুলি পরিচালনা করতে পারেন
- আমরা ভিউ রেন্ডার করি
এটি করার সঠিক উপায়
এখানে খুব ভাল কোড:
using System.Data.Entity;
public IQueryable<URL> GetAllUrls()
{
return context.Urls.AsQueryable();
}
public async Task<List<URL>> GetAllUrlsByUser(int userId) {
return await GetAllUrls().Where(u => u.User.Id == userId).ToListAsync();
}
দ্রষ্টব্য, আইকিউয়েরেবলের জন্য using System.Data.Entityপদ্ধতিটি ব্যবহার করার জন্য আপনাকে অবশ্যই যুক্ত করতে হবে ToListAsync()।
দ্রষ্টব্য, আপনার যদি ফিল্টারিং এবং পেজিং এবং স্টাফের প্রয়োজন না হয় তবে আপনার সাথে কাজ করার দরকার নেই IQueryable। আপনি কেবল ব্যবহার await context.Urls.ToListAsync()এবং উপাদানযুক্ত সঙ্গে কাজ করতে পারেন List<Url>।