2014-11-07 21 views
26

Ben şu iki basit örnekler var) (bekle.,Task.Delay() vs Task.Delay() beklemektedir C#

[Test] 
public void TestWait() 
{ 
    var t = Task.Factory.StartNew(() => 
    { 
     Console.WriteLine("Start"); 
     Task.Delay(5000).Wait(); 
     Console.WriteLine("Done"); 
    }); 
    t.Wait(); 
    Console.WriteLine("All done"); 
} 

[Test] 
public void TestAwait() 
{ 
    var t = Task.Factory.StartNew(async() => 
    { 
     Console.WriteLine("Start"); 
     await Task.Delay(5000); 
     Console.WriteLine("Done"); 
    }); 
    t.Wait(); 
    Console.WriteLine("All done"); 
} 

İlk örnek bir görevi baskılar "Başlat" yaratır bekler 5 saniye "Bitti" yazdırır ve sonra görevi sonlandırır. Görevin bitmesini ve ardından "Tamamlandı" yazısını bekliyorum. Testi çalıştırdığımda beklediğim gibi. İkinci sınama aynı davranışa sahip olmalıdır, ancak Görev içinde beklemenin, async kullanımı ve bekletme nedeniyle engellenmemesi dışında. Ancak bu test sadece "Start" yazıyor ve hemen "All done" ve "Bitti" yazdırılmıyor.

Ben bu davranışı elde neden bilmiyorum: Her türlü yardımı çok takdir :) S

+0

Task.Delay engellenmeyen olduğunu. İkinci yapıyı neden kullanacağın konusunda bir sebep göremiyorum. –

+0

@RoyDictus'un her ikisinin de kendi sorunları var. Asla 'Task.Wait() ' – Gusdor

+0

'un bir kopyasının [bir görevin içinde uyumsuzluk/bekleyiş bekleniyor] olasılığını asla çağırmamalısınız (http://stackoverflow.com/questions/24777253/waiting-for-async-await-inside-a- Görev) – i3arnon

cevap

27

ikinci testi iç içe geçmiş iki görevi vardır ve bu kullanmak gerekir düzeltmek için, en dıştaki biri için bekliyor t.Result.Wait(). t.Result içsel görevi alır.

ikinci yöntem

bu oran kabaca:

public void TestAwait() 
{ 
    var t = Task.Factory.StartNew(() => 
      { 
       Console.WriteLine("Start"); 
       return Task.Factory.StartNew(() => 
       { 
        Task.Delay(5000).Wait(); Console.WriteLine("Done"); 
       }); 
      }); 
      t.Wait(); 
      Console.WriteLine("All done"); 
} 

t.Wait() arayarak hemen döner dıştaki görev bekliyor.


Bu senaryo işlemek için sonuçta 'doğru' yolu hiç Wait kullanarak vazgeçmek ve sadece await kullanmaktır. Wait, bir UI'yi uyumsuz kodunuza ekledikten sonra deadlock issues neden olabilir.

[Test] 
    public async Task TestCorrect() //note the return type of Task. This is required to get the async test 'waitable' by the framework 
    { 
     await Task.Factory.StartNew(async() => 
     { 
      Console.WriteLine("Start"); 
      await Task.Delay(5000); 
      Console.WriteLine("Done"); 
     }).Unwrap(); //Note the call to Unwrap. This automatically attempts to find the most Inner `Task` in the return type. 
     Console.WriteLine("All done"); 
    } 

Daha da iyisi sadece uyumsuz işlemi başlaması Task.Run kullanın:

[TestMethod] 
    public async Task TestCorrect() 
    { 
     await Task.Run(async() => //Task.Run automatically unwraps nested Task types! 
     { 
      Console.WriteLine("Start"); 
      await Task.Delay(5000); 
      Console.WriteLine("Done"); 
     }); 
     Console.WriteLine("All done"); 
    } 
+2

Bu işe yaradı :) Bu arada, Task.Factory.StartNew yerine Task.Run kullanmak ya da Task.Run işleyemediğini Task.Factory.StartNew gereksinim duyacağı durumlar var mı? :) – svenskmand

+0

@svenskmand bkz. Http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx – brz

İlgili konular