Anahtar kelimeye sahip olmamaya ne dersiniz?
Derleyicinin çoğu zaman, eşzamansız bir yöntem çağırdığımda bunun sonucunu istediğini fark etmesini istiyorum.
Document doc = DownloadDocumentAsync();
Bu kadar. İnsanların bu şey için bir anahtar kelime düşünmekte zorlanmasının nedeni, "işler tamamen normal olsaydı yapacağınız şeyi yapmak" için bir anahtar kelimeye sahip olmak gibidir. Bu bir anahtar kelime gerektirmeyen, varsayılan olmalıdır.
Güncelleme
Başlangıçta derleyicinin ne yapacağını anlamak için tür çıkarımı ile akıllı olması gerektiğini önerdim. Bunun hakkında daha fazla düşünmek gerekirse, mevcut uygulamayı olduğu gibi CTP'de de saklıyorum, ancak await
anahtar kelimeyi açıkça kullanmanız gereken durumları azaltmak için birkaç önemsiz ekleme yapıyorum .
Biz bir öznitelik icat: [AutoAwait]
. Bu yalnızca yöntemlere uygulanabilir. Bunun yönteminize uygulanmasını sağlamanın bir yolu onu işaretlemektir async
. Ancak bunu elle de yapabilirsiniz, örneğin:
[AutoAwait]
public Task<Document> DownloadDocumentAsync()
Daha sonra async
, herhangi bir yöntemin içinde , derleyici bir çağrıyı beklemek istediğinizi varsayar DownloadDocumentAsync
, bu yüzden belirtmeniz gerekmez. Bu yönteme yapılan her çağrı otomatik olarak bekler.
Document doc = DownloadDocumentAsync();
Şimdi, "zekice olsun" ve elde etmek Task<Document>
istiyorsanız start
, yalnızca bir yöntem çağrısından önce görünebilen bir operatör kullanırsınız :
Task<Document> task = start DownloadDocumentAsync();
Temiz, sanırım. Şimdi düz bir yöntem çağrısı genellikle ne anlama gelir: yöntemin tamamlanmasını bekleyin. Ve start
farklı bir şey gösterir: beklemeyin.
Bir async
yöntemin dışında görünen kod için, bir yöntemi çağırmanıza izin vermenin tek yolu [AutoAwait]
öneki eklemektir start
. Bu, bir async
yöntemde görünüp görünmediğine bakılmaksızın aynı anlama gelen kodu yazmaya zorlar .
Sonra açgözlü olmaya başladım! :)
Öncelikle async
arayüz yöntemlerine başvurmak istiyorum :
interface IThing
{
async int GetCount();
}
Temel olarak, uygulama yönteminin geri dönmesi Task<int>
veya uyumlu bir şey olması gerektiği anlamına gelir await
ve yönteme çağrı yapanlar [AutoAwait]
davranış kazanacaktır .
Ayrıca yukarıdaki yöntemi uygularken, yazmak mümkün olmak istiyorum:
async int GetCount()
Bu yüzden Task<int>
dönüş türü olarak bahsetmek zorunda değilim .
Ayrıca, async
delege türlerine (sonuçta, bir yöntemle arabirimler gibidir) uygulamak istiyorum. Yani:
public async delegate TResult AsyncFunc<TResult>();
Bir async
delege - tahmin ettiniz - [AutoAwait]
davranışı var. Bir async
yöntemden onu çağırabilirsiniz ve otomatik olarak await
düzenlenir (yalnızca seçmezseniz start
). Ve eğer derseniz:
AsyncFunc<Document> getDoc = DownloadDocumentAsync;
Sadece işe yarıyor. Bu bir yöntem çağrısı değil. Henüz herhangi bir görev başlatılmadı - async delegate
bir görev değil. Görev yapmak için bir fabrika. Söyleyebilirsin:
Document doc = getDoc();
Ve bu bir görev başlatacak ve bitmesini bekleyip size sonuç verecektir. Veya şöyle diyebilirsiniz:
Task<Document> t = start getDoc();
Yani "sıhhi tesisat" sızıntı bu yerde bir yer bir async
yönteme delege yapmak istiyorsanız, bir async delegate
tür kullanmayı bilmek zorunda olmasıdır . Yani yerine Func
söylemelisin AsyncFunc
, vb. Bir gün bu tür şeyler geliştirilmiş tür çıkarımıyla düzeltilebilir.
Başka bir soru, sıradan (asenkron olmayan) bir yöntemle başla derseniz ne olması gerektiğidir. Açıkçası derleme hatası güvenli bir seçenek olacaktır. Ancak başka olasılıklar da var.