Sau khi đọc Eric Lippert’s answer Tôi có ấn tượng rằng await
và call/cc
là khá nhiều hai mặt của cùng một đồng tiền, với hầu hết các khác biệt cú pháp. Tuy nhiên, khi cố gắng thực sự thực hiện call/cc
trong C# 5, tôi gặp phải một vấn đề: hoặc là tôi hiểu nhầm cuộc gọi/cc (có thể là khá), hoặc chờ đợi chỉ gợi nhớ của cuộc gọi/cc.C# await vs continuations: không hoàn toàn giống nhau?
Cân nhắc pseudo-code như thế này:
function main:
foo();
print "Done"
function foo:
var result = call/cc(bar);
print "Result: " + result;
function bar(continuation):
print "Before"
continuation("stuff");
print "After"
Nếu sự hiểu biết của tôi về cuộc gọi/cc là đúng, thì đây nên in:
Before
Result: stuff
Done
Quan trọng hơn, khi việc tiếp tục được gọi, chương trình trạng thái được khôi phục cùng với lịch sử cuộc gọi, để foo
trả về thành main
và không bao giờ quay lại bar
.
Tuy nhiên, nếu được thực hiện bằng cách sử dụng await
trong C#, hãy gọi việc tiếp tục không khôi phục lịch sử cuộc gọi này. foo
trả về thành bar
và không có cách nào (mà tôi có thể thấy) rằng await
có thể được sử dụng để làm cho phần lịch sử cuộc gọi chính xác của việc tiếp tục.
Vui lòng giải thích: tôi đã hiểu sai hoàn toàn hoạt động của call/cc
hoặc là await
không hoàn toàn giống với call/cc
?
Bây giờ tôi biết câu trả lời, tôi phải nói rằng có lý do chính đáng để nghĩ về chúng khá giống nhau. Hãy xem xét những gì các chương trình trên trông giống như trong pseudo-C# -5:
function main:
foo();
print "Done"
async function foo:
var result = await(bar);
print "Result: " + result;
async function bar():
print "Before"
return "stuff";
print "After"
Vì vậy, trong khi phong cách C# 5 không bao giờ cho chúng ta một đối tượng tiếp tục vượt qua một giá trị cho, tổng thể tương đồng là khá ấn tượng. Ngoại trừ rằng lần này hoàn toàn rõ ràng rằng "Sau" không bao giờ được gọi, không giống như trong ví dụ thực sự/cuộc gọi cc, đó là một lý do khác để yêu C# và khen ngợi thiết kế của nó!
Timwi là chính xác; chờ đợi giống như một cuộc gọi "hiệu ứng cục bộ"/cc; đây là một sự tinh tế, tôi không nghĩ rằng để gọi ra trong câu trả lời ban đầu của tôi. Tôi đã cập nhật nó. –