উত্তর:
সেরা অনুশীলন হ'ল ফাংশনটি async void
কেবল আগুন এবং পদ্ধতিটি ভুলে গেলে চিহ্নিত করা, আপনি যদি অপেক্ষা করতে চান তবে আপনার এটি হিসাবে চিহ্নিত করা উচিত async Task
।
যদি আপনি এখনও অপেক্ষা করতে চান, তবে এটির মতো মোড়ানো করুন await Task.Run(() => blah())
await Task.Run(() => An_async_void_method_I_can_not_modify_now())
await Task.Run(() => blah())
বিভ্রান্তিকর। এটি অ্যাসিঙ্ক ফাংশন সমাপ্তির অপেক্ষায় নয় blah
, এটি কেবলমাত্র (তুচ্ছ) কাজটি তৈরির অপেক্ষায় রয়েছে এবং blah()
এটি সম্পন্ন হওয়ার সাথে সাথেই অব্যাহত থাকে ।
Thread.Sleep
নয়। এই প্রশ্নটি একটি async void
অনুষ্ঠানের অপেক্ষার বিষয়ে , বলুনasync void blah() { Task.Delay(10000); }
আপনি যদি নিজের ফাংশনের স্বাক্ষরটিকে এখানে পরিবর্তন করতে পারেন async Task
তবে আপনি এখানে উপস্থাপিত কোডটি ব্যবহার করতে পারেন
সবচেয়ে ভাল সমাধানটি ব্যবহার করা async Task
। আপনার async void
বেশ কয়েকটি কারণে এড়ানো উচিত , যার মধ্যে একটি হ'ল সামঞ্জস্যযোগ্যতা।
যদি পদ্ধতিটি ফিরে আসতে না পারে Task
(উদাহরণস্বরূপ, এটি কোনও ইভেন্ট হ্যান্ডলার), তবে আপনি SemaphoreSlim
যখন প্রস্থান করতে চলেছেন তখন আপনি পদ্ধতি সংকেতটি ব্যবহার করতে পারেন। এটি একটি finally
ব্লক করে বিবেচনা করুন ।
একটি অটোসেটসেন্ট করুন, ফাংশনটি কল করুন এবং তারপরে অটোসেটসেন্ট এ অপেক্ষা করুন এবং তারপরে এটি অ্যাসিঙ্ক শূন্যের মধ্যে সেট করুন যখন আপনি জানেন যে এটি সম্পন্ন হয়েছে।
আপনি এমন কোনও কার্যের জন্যও অপেক্ষা করতে পারেন যা আপনার অকার্যকর async থেকে ফিরে আসে
আপনাকে ম্যানুয়ালি সত্যিই কিছু করার দরকার নেই, await
কীওয়ার্ড blah()
ফিরিয়ে না দেওয়া পর্যন্ত ফাংশন সম্পাদনকে বিরতি দেয়।
private async void SomeFunction()
{
var x = await LoadBlahBlah(); <- Function is not paused
//rest of the code get's executed even if LoadBlahBlah() is still executing
}
private async Task<T> LoadBlahBlah()
{
await DoStuff(); <- function is paused
await DoMoreStuff();
}
T
অবজেক্ট blah()
রিটার্নের ধরণ
আপনি সত্যিই await
কোনও void
ফাংশন LoadBlahBlah()
করতে পারবেন না তাই হতে পারে নাvoid
LoadBlahBlah()
, শেষ নাblah()
আমি জানি এটি একটি পুরানো প্রশ্ন, তবে এটি এখনও একটি সমস্যা যা আমি প্রবেশ করি এবং এখনও অ্যাসিঙ্ক / অ্যাসিঙ্ক অকার্যকর স্বাক্ষর পদ্ধতিতে অপেক্ষা করার সময় এটি সঠিকভাবে করার কোনও সুস্পষ্ট সমাধান এখনও পাওয়া যায় না।
যাইহোক, আমি লক্ষ্য করেছি যে। ওয়েট () শূন্য পদ্ধতিতে সঠিকভাবে কাজ করছে।
এবং যেহেতু অ্যাসিঙ্ক অকার্যকর এবং অকার্যকর একই স্বাক্ষর রয়েছে, আপনার নিম্নলিখিতগুলি করতে হবে।
void LoadBlahBlah()
{
blah().Wait(); //this blocks
}
বিভ্রান্তিমূলকভাবে পর্যাপ্ত async / প্রতীক্ষা পরবর্তী কোডটিতে ব্লক করে না।
async void LoadBlahBlah()
{
await blah(); //this does not block
}
আপনি যখন আপনার কোডটি ছিন্ন করেন, তখন আমার অনুমান যে অ্যাসিঙ্ক শূন্যতা একটি অভ্যন্তরীণ টাস্ক তৈরি করে (ঠিক তেমনি অ্যাসিঙ্ক টাস্ক), তবে যেহেতু স্বাক্ষরটি অভ্যন্তরীণ টাস্কগুলি ফিরিয়ে আনতে সমর্থন করে না
এর অর্থ হ'ল অভ্যন্তরীণভাবে async শূন্য পদ্ধতিটি অভ্যন্তরীণভাবে async পদ্ধতিগুলি "অপেক্ষা" করতে সক্ষম হবে। কিন্তু অভ্যন্তরীণ টাস্কটি কখন সম্পূর্ণ হয় তা বাহ্যিকভাবে জানতে অক্ষম।
সুতরাং আমার উপসংহারটি হ'ল async অকার্যকর উদ্দেশ্য হিসাবে কাজ করছে, এবং যদি আপনার অভ্যন্তরীণ টাস্কের কাছ থেকে প্রতিক্রিয়া প্রয়োজন হয় তবে তার পরিবর্তে আপনাকে async কার্য স্বাক্ষর ব্যবহার করতে হবে।
আশা করি আমার ঝাঁকুনি উত্তরটি সন্ধানের জন্য কারও কাছে বোধগম্য হবে।
সম্পাদনা করুন: আমি কিছু উদাহরণ কোড তৈরি করেছি এবং এটি কী ঘটছে তা দেখার জন্য এটি সংক্ষেপিত করেছি।
static async void Test()
{
await Task.Delay(5000);
}
static async Task TestAsync()
{
await Task.Delay(5000);
}
রূপান্তরিত হয় (সম্পাদনা: আমি জানি যে বডি কোডটি এখানে নয় তবে স্টেটম্যাচাইনে রয়েছে, তবে স্টেটম্যাচিনগুলি মূলত অভিন্ন ছিল, তাই আমি এগুলি যুক্ত করতে বিরত হই নি)
private static void Test()
{
<Test>d__1 stateMachine = new <Test>d__1();
stateMachine.<>t__builder = AsyncVoidMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncVoidMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
}
private static Task TestAsync()
{
<TestAsync>d__2 stateMachine = new <TestAsync>d__2();
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncTaskMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
AsyncVoidMethodBuilder বা AsyncTaskMethodBuilder আসলেই স্টার্ট পদ্ধতিতে এমন কোনও কোড নেই যা তাদের ব্লক করার ইঙ্গিত দেয় এবং এগুলি শুরু হওয়ার পরে সর্বদা অ্যাসিঙ্ক্রোনালি চালিত হয়।
অর্থ ফেরত টাস্ক ব্যতীত, এটি সম্পূর্ণ কিনা তা যাচাই করার উপায় নেই।
যেমনটি প্রত্যাশা করা হয়েছিল, এটি কেবলমাত্র async চলমান কার্য শুরু করে এবং তারপরে এটি কোডে অবিরত থাকে। এবং অ্যাসিঙ্ক টাস্কটি প্রথমে এটি টাস্কটি শুরু করে এবং তারপরে এটি ফিরে আসে।
সুতরাং আমি অনুমান করি যে আমার উত্তরটি হ'ল অ্যাসিঙ্ক শূন্যতা কখনই ব্যবহার করা উচিত নয়, যদি টাস্কটি কখন করা হয় আপনার যদি এটির প্রয়োজন হয় তবে এটিই অ্যাসিঙ্ক টাস্কটি।