VS2012'yi aldım ve halletmeye çalışıyorum async.
Diyelim ki engelleme kaynağından bir değer alan bir yöntemim var. Yöntemin arayanının engellemesini istemiyorum. Değer geldiğinde çağrılan bir geri aramayı alma yöntemini yazabilirim, ancak C # 5 kullandığım için, yöntemi zaman uyumsuz yapmaya karar verdim, böylece arayanlar geri aramalarla uğraşmak zorunda kalmazlar:
// contrived example (edited in response to Servy's comment)
public static Task<string> PromptForStringAsync(string prompt)
{
return Task.Factory.StartNew(() => {
Console.Write(prompt);
return Console.ReadLine();
});
}
İşte onu çağıran örnek bir yöntem. Eğer PromptForStringAsynczaman uyumsuz değildi, bu yöntem bir geri içerisinde bir geri arama yuva gerektirecektir. Async ile yöntemimi şu çok doğal bir şekilde yazıyorum:
public static async Task GetNameAsync()
{
string firstname = await PromptForStringAsync("Enter your first name: ");
Console.WriteLine("Welcome {0}.", firstname);
string lastname = await PromptForStringAsync("Enter your last name: ");
Console.WriteLine("Name saved as '{0} {1}'.", firstname, lastname);
}
Çok uzak çok iyi. Ben ne zaman sorunudur diyoruz GetNameAsync:
public static void DoStuff()
{
GetNameAsync();
MainWorkOfApplicationIDontWantBlocked();
}
Bütün mesele, GetNameAsynceşzamansız olmasıdır. Ben yok istiyorum o ASAP MainWorkOfApplicationIDontWantBlocked geri almak istiyorum, çünkü, engellemek ve GetNameAsync arka planda onun şey yapalım. Ancak, bu şekilde çağırmak bana GetNameAsyncsatırda bir derleyici uyarısı veriyor :
Warning 1 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
"Mevcut yöntemin yürütülmesinin çağrı tamamlanmadan önce devam ettiğinin" tamamen farkındayım. Budur nokta , doğru asenkron kod?
Kodumun uyarı olmadan derlenmesini tercih ederim, ancak burada "düzeltecek" bir şey yok çünkü kod tam olarak yapmak istediğim şeyi yapıyor. Aşağıdakilerin dönüş değerini saklayarak uyarıdan kurtulabilirim GetNameAsync:
public static void DoStuff()
{
var result = GetNameAsync(); // supress warning
MainWorkOfApplicationIDontWantBlocked();
}
Ama artık gereksiz kodum var. Visual Studio, normal "hiç kullanılmayan değer" uyarısını bastırdığı için bu gereksiz kodu yazmaya zorlandığımı anlıyor gibi görünüyor.
GetNameAsync'i zaman uyumsuz olmayan bir yöntemde sararak da uyarıdan kurtulabilirim:
public static Task GetNameWrapper()
{
return GetNameAsync();
}
Ama bu daha da gereksiz bir kod. Bu yüzden kod yazmalıyım, gereksiz bir uyarıya ihtiyacım yok veya hoşgörülü değilim.
Eşzamansız kullanımımla ilgili burada yanlış olan bir şey mi var?
GetNameAsyncyani (kullanıcı tarafından sağlandı Tam isim Task<Name>yerine sadece dönen daha Task? DoStuffO zaman bu görevi depolayabilir ve ya awaitonu sonra diğer yöntemde, hatta bu diğer görevi geçmesi yöntem olabilir awaitya Waitda uygulamasının içinde bir yerde.
asyncAnahtar kelimeyi kaldırın .
PromptForStringAsyncgerekenden daha fazla iş yaparsınız; sadece sonucunu döndürTask.Factory.StartNew. Bu zaten konsola girilen dizenin değeri olan bir görevdir. Sonucun geri gelmesini beklemeye gerek yok; bunu yapmak yeni bir değer katmaz.