আমি Task.Wait
এবং এর মধ্যে পার্থক্যটি বেশ বুঝতে পারি না await
।
আমার একটি এএসপি.নেট ওয়েবএপিআই পরিষেবাতে নিম্নলিখিত ফাংশনগুলির অনুরূপ কিছু রয়েছে:
public class TestController : ApiController
{
public static async Task<string> Foo()
{
await Task.Delay(1).ConfigureAwait(false);
return "";
}
public async static Task<string> Bar()
{
return await Foo();
}
public async static Task<string> Ros()
{
return await Bar();
}
// GET api/test
public IEnumerable<string> Get()
{
Task.WaitAll(Enumerable.Range(0, 10).Select(x => Ros()).ToArray());
return new string[] { "value1", "value2" }; // This will never execute
}
}
কোথায় Get
অচলাবস্থা হবে।
এর কারণ কী হতে পারে? আমি যখন ব্লকিং ওয়েট না করে ব্যবহার করি তখন কেন এই সমস্যার কারণ হয় না await Task.Delay
?
Task.Delay(1).Wait()
মূলত ঠিক একই জিনিস Thread.Sleep(1000)
। প্রকৃত উত্পাদন কোডে এটি খুব কমই উপযুক্ত।
WaitAll
অচলাবস্থা সৃষ্টি করছে। আরও তথ্যের জন্য আমার উত্তরটিতে আমার ব্লগের লিঙ্কটি দেখুন। await Task.WhenAll
পরিবর্তে আপনার ব্যবহার করা উচিত ।
ConfigureAwait(false)
একটি একক থেকে কল Bar
বা Ros
অচলাবস্থা করবে না, কিন্তু কারণ আপনি একটি গণনীয় যে বেশী একটি তৈরি এবং তারপর ঐ সব অপেক্ষায় আছে, প্রথম বার দ্বিতীয় অচলাবস্থা হবে। আপনি যদি await Task.WhenAll
সমস্ত কাজের জন্য অপেক্ষা না করে, যাতে আপনি এএসপি প্রসঙ্গে অবরুদ্ধ না হন, আপনি পদ্ধতিটি স্বাভাবিকভাবে ফিরে আসতে দেখবেন।
.ConfigureAwait(false)
গাছ আপ সব পথ পর্যন্ত আপনি অবরোধ যে ভাবে কিছুই নয় কি কখনো প্রধান প্রসঙ্গ পেতে চেষ্টা; যে কাজ করবে। অন্য বিকল্পটি একটি অভ্যন্তরীণ সিঙ্ক্রোনাইজেশন প্রসঙ্গটি স্পিন করা উচিত। লিঙ্ক । আপনি করা যদি Task.WhenAll
একটি ইন AsyncPump.Run
এটা কার্যকরভাবে আপনাকে ছাড়াই পুরো জিনিস উপর অবরোধ করবে ConfigureAwait
যে কোন স্থানে, কিন্তু সম্ভবত একটি মাত্রাতিরিক্ত জটিল সমাধান যে।
Task.Delay(1).Wait()
যা যথেষ্ট ভাল।