তিন কর্ম দেওয়া - FeedCat()
, SellHouse()
এবং BuyCar()
, দুই আকর্ষণীয় মামলা থাকে: পারেন তারা সবাই সম্পূর্ণ সিঙ্ক্রোনাস (কিছু কারণে, সম্ভবত ক্যাশে বা কোন ত্রুটির), অথবা তারা করবেন না।
আসুন আমরা প্রশ্ন থেকে বলি:
Task<string> DoTheThings() {
Task<Cat> x = FeedCat();
Task<House> y = SellHouse();
Task<Tesla> z = BuyCar();
// what here?
}
এখন, একটি সহজ পদ্ধতি হবে:
Task.WhenAll(x, y, z);
তবে ... ফলাফলগুলি প্রক্রিয়া করার জন্য এটি সুবিধাজনক নয়; আমরা সাধারণত চাইawait
:
async Task<string> DoTheThings() {
Task<Cat> x = FeedCat();
Task<House> y = SellHouse();
Task<Tesla> z = BuyCar();
await Task.WhenAll(x, y, z);
// presumably we want to do something with the results...
return DoWhatever(x.Result, y.Result, z.Result);
}
তবে এটি প্রচুর ওভারহেড করে এবং বিভিন্ন অ্যারে (অ্যারে সহ params Task[]
) এবং তালিকাগুলি (অভ্যন্তরীণভাবে) বরাদ্দ করে । এটি কাজ করে, তবে এটি দুর্দান্ত আইএমও নয়। অনেকগুলি উপায়ে কোনও অপারেশন ব্যবহার করা সহজasync
এবং await
প্রতিটি পরিবর্তে:
async Task<string> DoTheThings() {
Task<Cat> x = FeedCat();
Task<House> y = SellHouse();
Task<Tesla> z = BuyCar();
// do something with the results...
return DoWhatever(await x, await y, await z);
}
উপরে মন্তব্য কিছু ব্যবহার বিপক্ষে await
পরিবর্তে Task.WhenAll
তোলে কোনো পার্থক্য কিভাবে কর্ম চালানোর (একই সময়ে, ক্রমানুসারে, ইত্যাদি) জন্য। সর্বোচ্চ স্তরে, / এর জন্য ভাল সংকলক সমর্থনের Task.WhenAll
পূর্বাভাস দেয় এবং যখন সেই জিনিসগুলির অস্তিত্ব ছিল না তখন তা কার্যকর ছিল । 3 টি বিচক্ষণ কাজের পরিবর্তে আপনার যখন কাজগুলির একটি স্বেচ্ছাসেবী অ্যারে থাকে তখন এটিও কার্যকর।async
await
তবে: আমাদের এখনও সমস্যা আছে যা async
/ await
ধারাবাহিকতার জন্য প্রচুর সংকলক শব্দ উত্পন্ন করে। এটি সম্ভবত যদি কাজগুলি হতে পারে সিঙ্ক্রোনাসভাবে শেষ , তবে আমরা একটি অ্যাসিঙ্ক্রোনাস ফ্যালব্যাক সহ একটি সিঙ্ক্রোনাস পথে নির্মাণের মাধ্যমে এটি অনুকূলিত করতে পারি:
Task<string> DoTheThings() {
Task<Cat> x = FeedCat();
Task<House> y = SellHouse();
Task<Tesla> z = BuyCar();
if(x.Status == TaskStatus.RanToCompletion &&
y.Status == TaskStatus.RanToCompletion &&
z.Status == TaskStatus.RanToCompletion)
return Task.FromResult(
DoWhatever(a.Result, b.Result, c.Result));
// we can safely access .Result, as they are known
// to be ran-to-completion
return Awaited(x, y, z);
}
async Task Awaited(Task<Cat> a, Task<House> b, Task<Tesla> c) {
return DoWhatever(await x, await y, await z);
}
এই "অ্যাসিঙ্ক ফ্যালব্যাক সহ সিঙ্ক পাথ" পদ্ধতির ক্রমবর্ধমান বিশেষত উচ্চ পারফরম্যান্স কোড যেখানে সিঙ্ক্রোনাস সম্পূর্ণকরণ তুলনামূলকভাবে ঘন ঘন হয় increasingly মনে রাখবেন যে সমাপ্তি সর্বদা সত্যই অ্যাসিনক্রোনাস থাকে তবে এগুলি কোনও উপকারে আসবে না।
অতিরিক্ত জিনিসগুলি যা এখানে প্রয়োগ হয়:
সাম্প্রতিক সি # এর সাথে, async
ফালব্যাক পদ্ধতিটির জন্য একটি সাধারণ প্যাটার্নটি সাধারণত স্থানীয় ফাংশন হিসাবে প্রয়োগ করা হয়:
Task<string> DoTheThings() {
async Task<string> Awaited(Task<Cat> a, Task<House> b, Task<Tesla> c) {
return DoWhatever(await a, await b, await c);
}
Task<Cat> x = FeedCat();
Task<House> y = SellHouse();
Task<Tesla> z = BuyCar();
if(x.Status == TaskStatus.RanToCompletion &&
y.Status == TaskStatus.RanToCompletion &&
z.Status == TaskStatus.RanToCompletion)
return Task.FromResult(
DoWhatever(a.Result, b.Result, c.Result));
// we can safely access .Result, as they are known
// to be ran-to-completion
return Awaited(x, y, z);
}
পছন্দ ValueTask<T>
করার Task<T>
যদি বিভিন্ন রিটার্ন মান কি কখনো সম্পূর্ণরূপে সিঙ্ক্রোনাস জিনিস ভাল সুযোগ:
ValueTask<string> DoTheThings() {
async ValueTask<string> Awaited(ValueTask<Cat> a, Task<House> b, Task<Tesla> c) {
return DoWhatever(await a, await b, await c);
}
ValueTask<Cat> x = FeedCat();
ValueTask<House> y = SellHouse();
ValueTask<Tesla> z = BuyCar();
if(x.IsCompletedSuccessfully &&
y.IsCompletedSuccessfully &&
z.IsCompletedSuccessfully)
return new ValueTask<string>(
DoWhatever(a.Result, b.Result, c.Result));
// we can safely access .Result, as they are known
// to be ran-to-completion
return Awaited(x, y, z);
}
যদি সম্ভব হয় তবে অগ্রাধিকার IsCompletedSuccessfully
দিন Status == TaskStatus.RanToCompletion
; এটি এখন নেট নেট Task
এবং এর জন্য সর্বত্র রয়েছে everywhereValueTask<T>