Oldukça arasındaki farkı anlayamıyorum Task.Wait
ve 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.WhenAll
yerine kullanmalısınız .
ConfigureAwait(false)
bir tek çağrı Bar
veya Ros
kilitlenme olmaz, ancak bunların hepsi bekleyen sonra birden fazla yaratmak ve bir enumerator çünkü, ilk çubuk ikinci kilitlenmeye. Eğer varsa await Task.WhenAll
yerine 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.WhenAll
bir AsyncPump.Run
şekilde engeller ConfigureAwait
, ancak bu muhtemelen aşırı karmaşık bir çözümdür.
Task.Delay(1).Wait()
yeterince iyi.