Son zamanlarda C # 5.0 şaşırtıcı async-bekliyor desen yeterince alamıyorum görünmüyor . Tüm hayatım boyunca neredeydin?
Basit sözdiziminden kesinlikle heyecan duyuyorum, ancak küçük bir zorluk yaşıyorum. Benim sorunum, asenkron fonksiyonların normal fonksiyonlardan tamamen farklı bir beyanı olmasıdır. Sadece zaman uyumsuz işlevler diğer zaman uyumsuz işlevleri üzerinde bekleyebilir beri, bazı eski engelleme kodunu zaman uyumsuzluğa aktarmaya çalıştığımda, dönüştürmem gereken işlevlerin domino etkisi yaşıyorum.
İnsanlar buna bir zombi istilası olarak atıfta bulunuyorlar . Zaman uyumsuz kodunuzda bir ısırık aldığında, gittikçe büyür. Taşıma işlemi zor değildir, sadece async
beyanda bulunmak ve dönüş değerini ile sarmaktır Task<>
. Ancak eski senkron kodu taşırken bunu tekrar tekrar yapmak can sıkıcı bir durum.
Bana göre, her iki işlev türünün (async ve normal eski eşitleme) aynı sözdizimine sahip olması çok daha doğal olacaktır. Eğer durum buysa, taşıma işlemi sıfır çaba gerektirecek ve iki form arasında ağrısız bir şekilde geçiş yapabilirdim.
Bu kuralları izlersek bunun işe yarayabileceğini düşünüyorum:
Zaman uyumsuz işlevler
async
artık bildirim gerektirmez . Geri dönüş türlerinin sarılması gerekmezTask<>
. Derleyici, derleme sırasında kendiliğinden bir eşzamansızlık işlevi belirler ve gerektiğinde Görev <> sarma işlemini otomatik olarak yapar.Artık eşzamansız işlevlere ateşle ve unut çağrılarına son. Bir eşzamansız işlevi çağırmak istiyorsanız, onu beklemeniz gerekir. Zaten ateşle ve unut kullanıyorum ve çılgın yarış koşullarının veya kilitlenmelerin tüm örnekleri her zaman bunlara dayanıyor gibi görünüyor. Bence çok kafa karıştırıcılar ve kaldıraçlı zihniyetle “temasta kalmıyorlar”.
Eğer gerçekten ateş et ve unut olmadan yaşayamazsan, bunun için özel bir sözdizimi olacak. Her durumda, bahsettiğim basit birleşik sözdiziminin bir parçası olmayacak.
Eşzamansız bir çağrıyı belirtmek için ihtiyacınız olan tek anahtar kelime
await
. Bekliyorsanız, çağrı zaman uyumsuzdur. Eğer yapmazsanız, çağrı düz eski eşzamanlıdır (unutmayın, artık ateşle ve unut.Derleyici async işlevlerini otomatik olarak tanımlayacaktır (artık özel bir bildirimi olmadığından). Kural 4 bunu yapmayı çok kolaylaştırır - bir fonksiyonun içinde bir
await
çağrı varsa , bu zaman uyumsuzdur.
Bu işe yarayabilir mi? yoksa bir şey mi kaçırıyorum? Bu birleşik sözdizimi çok daha akıcıdır ve zombi istilasını tamamen çözebilir.
Bazı örnekler:
// assume this is an async function (has await calls inside)
int CalcRemoteBalanceAsync() { ... }
// assume this is a regular sync function (has no await calls inside)
int CalcRemoteBalance() { ... }
// now let's try all combinations and see what they do:
// this is the common synchronous case - it will block
int b1 = CalcRemoteBalance();
// this is the common asynchronous case - it will not block
int b2 = await CalcRemoteBalanceAsync();
// choosing to call an asynchronous function in a synchronous manner - it will block
// this syntax was used previously for async fire-and-forget, but now it's just synchronous
int b3 = CalcRemoteBalanceAsync();
// strange combination - it will block since it's calling a synchronous function
// it should probably show a compilation warning though
int b4 = await CalcRemoteBalance();
Not: Bu ilginç bir devamıdır ilgili tartışma SO içinde
await
hemen yapmak zorunda olmamanızdır . Gibi bir şey yapabilirsiniz var task = FooAsync(); Bar(); await task;
. Bunu teklifinizde nasıl yapardım?
async
. Bence bu büyük avantajlardan biri async
- await
: kolayca senkronize olmayan işlemler oluşturmak için izin verir (ve sadece en basit "başlangıç A, A için bekleyin, B başlatmak, B için bekleyin" yolu). Ve zaten tam olarak bu amaç için özel bir sözdizimi var: buna denir await
.