zaman uyumsuz operasyonlar yakalama İstisnalar

oy
9

Burada zaman uyumsuz hakkında daha fazla okuyorum: http://msdn.microsoft.com/en-us/library/hh873173(v=vs.110).aspx

Bu örnekte geçiyor:

Task<bool> [] recommendations = …;
while(recommendations.Count > 0)
{ 
    Task<bool> recommendation = await Task.WhenAny(recommendations);    
    try
    {
        if (await recommendation) BuyStock(symbol);
        break;
    }
    catch(WebException exc)
    {
        recommendations.Remove(recommendation);
    }
}

Zaten üzerinde bekliyor sahnede oluyorum Merak ediyorum, Task.WhenAnyben try'ın içine tekrar bekliyor gerekiyor neden?

Zaten bu yaptıysak: Task<bool> recommendation = await Task.WhenAny(recommendations); Neden bunu:if (await recommendation) BuyStock(symbol);

Oluştur 02/09/2014 saat 12:14
kaynak kullanıcı
Diğer dillerde...                            


6 cevaplar

oy
8

İlk awaituyumsuz (yani tamamlayan ilk görev için beklemek için var recommendation). İkinci awaittamamlanmış görevin dışına fiili sonucunu çıkarmak ve görev depolanan istisnalar atmak sadece vardır. ( O tamamlanmış bir görevi bekliyor optimize edilmiştir ve senkronize bir şekilde çalışmaya edeceğini hatırlamak önemlidir ).

Kullanıyor olur sonuç almak için farklı bir seçenek Task<T>.Result, ancak bunun istisnaları işleme biçiminde farklıdır. awaitGerçek istisna olacaktır (örn WebException) ise Task<T>.Resultbir atardı AggregateExceptioniçeride fiili durum içeren.

Task<bool> [] recommendations = …;
while(recommendations.Count > 0)
{ 
    Task<bool> recommendation = await Task.WhenAny(recommendations);    
    try
    {
        if (recommendation.Result) 
        {
            BuyStock(symbol);
        }
        break;
    }
    catch(AggregateException exc)
    {
        exc = exc.Flatten();
        if (exc.InnerExceptions[0] is WebException)
        {
            recommendations.Remove(recommendation);
        }
        else
        {
            throw;
        }
    }
}

Açıkça görevi bekleyen basittir ve bu yüzden bir görevin dışında bir sonuç almak için önerilen bir yoldur.

Cevap 02/09/2014 saat 12:20
kaynak kullanıcı

oy
4

Haklısın. Bu gerekli değil. Sen ile değiştirin olabilir

if (recommendation.Result) 
    BuyStock(symbol);

Ayrıca unutmayınız awaittamamlanan görev verildiğinde (devamı set olmaz) bekliyor olmayacaktır. Bu sadece bir optimizasyon olarak bu durumda eş zamanlı çalıştırır. Ben yazar o optimizasyonu güçlendirir sanırım.

Yazar, bu şekilde yazdım neden sorarsanız, tutarlılık olabilir? sadece o biliyor !.

Cevap 02/09/2014 saat 12:20
kaynak kullanıcı

oy
0

Çünkü Task.WhenAny<TResult>(IEnumerable<Task<TResult>> tasks)getiriler bir Task<Task<TResult>>. Dış görev (yarattığı bir Task.WhenAnygörevlerden herhangi birini bir sonucu olarak tamamlanmış görev ile tamamlar geçirilen zaman çağrı) tamamlayacak.

Cevap 02/09/2014 saat 12:20
kaynak kullanıcı

oy
1

Zaten bu yaptıysak: Görev öneri = Task.WhenAny (öneriler) beklemektedir; Neden bunu: BuyStock (sembol) (öneri bekliyor) eğer;

Çünkü Task.WhenAnydöner a Task<Task<bool>>ve outter kakışıyor istediğiniz Taskçıkan bool almak için. Sen erişerek aynı yapabileceğini Task.Resultiade malıTask

Cevap 02/09/2014 saat 12:21
kaynak kullanıcı

oy
0

Diğer cevaplar zorunda olduğuna dikkat çekmişlerdir awaittarafından döndürülen görev await Task.WhenAlldönüş değeri (alternatif olarak kullanabilirsiniz unwrap Resultözelliği).

Ancak, aynı zamanda try / catch kurtulabilirsiniz (ve gereksiz istisna yakalamak önlemek için iyi bir şey)

Task<bool> recommendation = await Task.WhenAny(recommendations);    
if(!recommendation.IsFaulted)
{
    if (await recommendation) BuyStock(symbol);
    break;
}
else
{
    if(recommendation.Exception.InnerExceptions[0] is WebException)
    {
        recommendations.Remove(recommendation);
    }
    else
    {
        throw recommendation.Exception.InnerExceptions[0];
    }
}
Cevap 02/09/2014 saat 12:34
kaynak kullanıcı

oy
5

Kullanımı awaitburada istenen hata işleme semantiğini oluşturur. Kullandığı takdirde Resultyerine awaito AggregateExceptiondoğrudan rethrown olacaktır; kullanırken awaitiçindeki ilk istisna AggregateExceptionçekilirse bir o istisna yeniden atılır. Bu kodun yazar istediği temizleyin WebExceptionziyade bir daha atılmasına AggregateExceptiono elle unwrap ihtiyacı olduğu bildirildi.

o emin bir başka yaklaşım, kullanmış olabilir. Bu sadece bu onu kökten kod tarzını değiştirerek yerine geleneksel senkron kodu gibi daha fazla kod yazmak için izin verdiği kod yazar, tercih edilen yaklaşım oldu.

Cevap 02/09/2014 saat 14:04
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more