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 awaitanahtar 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 startfarklı bir şey gösterir: beklemeyin.
Bir asyncyö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 asyncyö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 asyncarayü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 awaitve 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, asyncdelege türlerine (sonuçta, bir yöntemle arabirimler gibidir) uygulamak istiyorum. Yani:
public async delegate TResult AsyncFunc<TResult>();
Bir asyncdelege - tahmin ettiniz - [AutoAwait]davranışı var. Bir asyncyöntemden onu çağırabilirsiniz ve otomatik olarak awaitdü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 delegatebir 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 asyncyönteme delege yapmak istiyorsanız, bir async delegatetür kullanmayı bilmek zorunda olmasıdır . Yani yerine Funcsö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.