Hãy xem xét phương pháp không đồng bộ rất đơn giản này:
static async Task myMethodAsync()
{
await Task.Delay(500);
}
Khi tôi biên dịch điều này với VS2013 (trình biên dịch trước Roslyn), máy trạng thái được tạo là một cấu trúc.
private struct <myMethodAsync>d__0 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
Khi tôi biên dịch nó với VS2015 (Roslyn), mã được tạo là:
private sealed class <myMethodAsync>d__1 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
Như bạn có thể thấy Roslyn tạo một lớp (chứ không phải một cấu trúc). Nếu tôi nhớ không nhầm thì những triển khai đầu tiên của hỗ trợ async / await trong trình biên dịch cũ (tôi đoán là CTP2012) cũng đã tạo ra các lớp và sau đó nó được thay đổi thành cấu trúc vì lý do hiệu suất. (trong một số trường hợp, bạn hoàn toàn có thể tránh quyền anh và phân bổ đống…) (Xem phần này )
Có ai biết tại sao điều này lại được thay đổi ở Roslyn không? (Tôi không có bất kỳ vấn đề nào liên quan đến điều này, tôi biết rằng thay đổi này là minh bạch và không thay đổi hành vi của bất kỳ mã nào, tôi chỉ tò mò)
Biên tập:
Câu trả lời từ @Damien_The_Un Believer (và mã nguồn :)) imho giải thích mọi thứ. Hành vi được mô tả của Roslyn chỉ áp dụng cho bản dựng gỡ lỗi (và điều đó là cần thiết vì giới hạn CLR được đề cập trong nhận xét). Trong Release, nó cũng tạo ra một cấu trúc (với tất cả các lợi ích của điều đó ..). Vì vậy, đây có vẻ là một giải pháp rất thông minh để hỗ trợ cả Chỉnh sửa và Tiếp tục và hiệu suất tốt hơn trong sản xuất. Công cụ thú vị, cảm ơn cho tất cả những người đã tham gia!
async
các phương thức hầu như luôn có một điểm không đồng bộ thực sự - một điểmawait
mang lại quyền điều khiển, điều này sẽ yêu cầu cấu trúc phải được đóng hộp. Tôi tin rằng cấu trúc sẽ chỉ làm giảm áp lực bộ nhớ choasync
các phương pháp đã tình cờ chạy đồng bộ.