Oldukça arasındaki farkı anlayamıyorum Task.Waitve await.
Bir ASP.NET WebAPI hizmetinde aşağıdaki işlevlere benzer bir şey var:
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
}
}
Nerede Getçıkacak.
Buna ne sebep olabilir? Bir engelleme beklemesini kullanmak yerine neden bir soruna neden olmaz await Task.Delay?
Task.Delay(1).Wait()temel olarak aynı şeydir Thread.Sleep(1000). Gerçek üretim kodunda nadiren uygundur.
WaitAllçıkmaza neden oluyorsunuz . Daha fazla ayrıntı için cevabımdaki bloguma bağlantıya bakın. Bunun await Task.WhenAllyerine kullanmalısınız .
ConfigureAwait(false)bir tek çağrı Barveya Roskilitlenme olmaz, ancak bunların hepsi bekleyen sonra birden fazla yaratmak ve bir enumerator çünkü, ilk çubuk ikinci kilitlenmeye. Eğer varsa await Task.WhenAllyerine ASP bağlamı engellemeyecek şekilde bu, görevlerin tümünü bekleyen, sen yöntem dönüşü normal olarak göreceksiniz.
.ConfigureAwait(false) ağacın yukarı tüm yol sen, bu şekilde hiçbir şey olduğu blok kadar hiç geri ana bağlamına almaya çalışırken; bu işe yarar. Başka bir seçenek, bir iç senkronizasyon bağlamını döndürmek olacaktır. Bağlantı . Eğer içine koyarsanız, herhangi bir yere ihtiyaç duymadan her şeyi etkili Task.WhenAllbir AsyncPump.Runşekilde engeller ConfigureAwait, ancak bu muhtemelen aşırı karmaşık bir çözümdür.
Task.Delay(1).Wait()yeterince iyi.