Tamam, işte benim almam.
On yıllardır bilinen koroutin adı verilen bir şey var . ("Knuth and Hopper" -class "onlarca yıldır") Bunlar alt işlevlerin sadece işlev başlatma ve geri dönüş ifadesinde kontrolü alıp bırakmazlar, aynı zamanda belirli noktalarda da ( süspansiyon noktaları ) yaparlar . Bir alt rutin, süspansiyon noktası olmayan bir koroutindir.
Aşağıdaki makalede "protothreads" ile ilgili olarak gösterildiği gibi, C makrolarıyla uygulanması kolay DÜZ KOLAYDIR. ( http://dunkels.com/adam/dunkels06protothreads.pdf ) Okuyun. Bekleyeceğim...
Bunun sonucu, makroların büyük bir switchcase her bir askı noktasında ve bir etiket . Her askıya alma noktasında, işlev hemen takip eden caseetiketin değerini saklar , böylece bir dahaki sefere yürütme işlemine nerede devam edileceğini bilir. Ve kontrolü arayan kişiye geri döndürür.
Bu, "protothread" de açıklanan kodun görünür kontrol akışını değiştirmeden yapılır.
Şimdi tüm bu "prototipleri" çağıran büyük bir döngüye sahip olduğunuzu ve aynı anda tek bir iş parçacığında "protothreads" yürüttüğünüzü hayal edin.
Bu yaklaşımın iki dezavantajı vardır:
- Yeniden başlatmalar arasındaki durumu yerel değişkenlerde tutamazsınız.
- "Protothread" i rastgele bir arama derinliğinden askıya alamazsınız. (tüm askı noktaları 0 seviyesinde olmalıdır)
Her ikisi için de geçici çözümler vardır:
- Tüm yerel değişkenler prototipin içeriğine (protothread'in bir sonraki devam etme noktasını saklaması gerektiği için zaten gerekli olan bağlam) alınmalıdır.
- Gerçekten bir prototipten başka bir prototip çağırmanız gerektiğini düşünüyorsanız, bir çocuk prototipi "doğurun" ve çocuğun tamamlanmasına kadar askıya alın.
Ve makroların ve geçici çözümün yaptığı yeniden yazma işini yapmak için derleyici desteğine sahipseniz, protothread kodunuzu yalnızca bir anahtar kelimeyle askıya alma noktaları istediğiniz gibi yazıp yazabilirsiniz.
Ve işte bu asyncve awaitbununla ilgili: (yığınsız) couteinler yaratmak.
C # 'daki eşbiçimler (jenerik veya jenerik olmayan) sınıfının nesneleri olarak yeniden tanımlanır Task.
Bu anahtar kelimeleri çok yanıltıcı buluyorum. Zihinsel okumam:
async "askıya alınabilir" olarak
await "tamamlanıncaya kadar askıya al" olarak
Task "gelecek ..." olarak
Şimdi. İşlevi gerçekten işaretlememiz gerekiyor asyncmu? İşlevi bir program yapmak için kod yeniden yazma mekanizmalarını tetiklemesi gerektiğini söylemenin yanı sıra, bazı belirsizlikleri de giderir. Bu kodu düşünün.
public Task<object> AmIACoroutine() {
var tcs = new TaskCompletionSource<object>();
return tcs.Task;
}
asyncZorunlu olmadığını varsayarsak , bu bir koroutin veya normal bir işlev midir? Derleyici bunu bir program olarak yeniden yazmalı mı, yazmamalı mı? Her ikisi de farklı nihai anlambilim ile mümkün olabilir.