Khi tôi viết mã không đồng bộ bằng async / await, thường là ConfigureAwait(false)để tránh nắm bắt bối cảnh, mã của tôi sẽ chuyển từ một chuỗi luồng này sang luồng tiếp theo sau mỗi chuỗi await. Điều này làm tăng mối quan tâm về an toàn chủ đề. Mã này có an toàn không?
static async Task Main()
{
int count = 0;
for (int i = 0; i < 1_000_000; i++)
{
Interlocked.Increment(ref count);
await Task.Yield();
}
Console.WriteLine(count == 1_000_000 ? "OK" : "Error");
}
Biến inày không được bảo vệ và được truy cập bởi nhiều luồng xử lý nhóm *. Mặc dù mô hình truy cập là không đồng thời, nhưng về mặt lý thuyết, mỗi luồng sẽ tăng giá trị được lưu trong bộ nhớ cache cục bộ i, dẫn đến hơn 1.000.000 lần lặp. Tôi không thể tạo ra kịch bản này trong thực tế. Mã ở trên luôn in OK trong máy của tôi. Điều này có nghĩa là mã là chủ đề an toàn? Hoặc tôi nên đồng bộ hóa quyền truy cập vào ibiến bằng cách sử dụng a lock?
(* một chuyển đổi luồng xảy ra trung bình cứ sau 2 lần lặp, theo các thử nghiệm của tôi)
ilà lưu trữ trong mỗi chủ đề? Xem điều này SharpLab IL để đào sâu hơn.