Đầu tiên một chút thông tin cơ bản. Tôi đang trong quá trình tạo mã thư viện C# hiện có phù hợp để thực hiện trên WinRT. Là một phần nhỏ của mã này sâu xuống cần phải làm một tập tin nhỏ IO, đầu tiên chúng tôi đã cố gắng để giữ cho mọi thứ đồng bộ và sử dụng Task.Wait() để ngăn chặn các chủ đề chính cho đến khi tất cả IO đã được thực hiện.Tại sao task.Wait không bế tắc trên một chủ đề không phải là ui? Hay tôi chỉ may mắn?
Chắc chắn, chúng tôi nhanh chóng phát hiện ra dẫn đến bế tắc.
Sau đó tôi thấy mình thay đổi rất nhiều mã trong một mẫu thử nghiệm để làm cho nó "không đồng bộ". Đó là, tôi đã chèn async và chờ đợi từ khóa, và tôi đã thay đổi phương thức trả về kiểu cho phù hợp. Điều này là rất nhiều công việc - quá nhiều công việc vô nghĩa trong thực tế -, nhưng tôi đã có nguyên mẫu làm việc theo cách này.
Sau đó, tôi đã làm một thí nghiệm, và tôi chạy mã gốc với tuyên bố Chờ trên một sợi riêng biệt:
System.Threading.Tasks.Task.Run(()=> Draw(..., cancellationToken)
Không bế tắc!
Bây giờ tôi đang bối rối nghiêm trọng, bởi vì tôi nghĩ rằng tôi hiểu cách hoạt động của chương trình không đồng bộ. Mã của chúng tôi không (chưa) sử dụng ConfigureAwait (sai) ở tất cả. Vì vậy, tất cả các câu lệnh chờ đợi sẽ tiếp tục trong bối cảnh tương tự như chúng được viện dẫn. Phải không? Tôi giả định điều đó có nghĩa là: cùng một chủ đề. Bây giờ nếu thread này đã gọi "Wait", điều này cũng sẽ dẫn đến một bế tắc. Nhưng nó không.
Bạn có giải thích rõ ràng về đá nào không?
Câu trả lời cho điều này sẽ xác định xem tôi có thực sự làm rối tung mã của chúng tôi hay không bằng cách chèn nhiều từ khóa không đồng bộ/chờ đợi có điều kiện hoặc tôi sẽ giữ nó sạch sẽ và chỉ sử dụng chuỗi. với chỗ ấy. Nếu sự tiếp tục được chạy bởi một chuỗi không bị chặn tùy ý, mọi thứ sẽ ổn. Tuy nhiên, nếu chúng được chạy bởi chuỗi giao diện người dùng, chúng tôi có thể gặp sự cố nếu việc tiếp tục tính toán tốn kém.
Tôi hy vọng rằng vấn đề là rõ ràng. Nếu không, vui lòng cho tôi biết.
Cảm ơn thông tin. Điều này giải thích khá nhiều. –
Để làm rối tung mọi thứ: đây là mã thư viện hiện có được nhắm mục tiêu ở nhiều nền tảng (.Net), không chỉ WinRT. Chúng tôi muốn sử dụng cùng một mã cho tất cả các nền tảng, vì vậy chúng tôi phải sử dụng #if để tránh chờ/không đồng bộ cho các nền tảng không có sẵn. Ngoài ra, chúng tôi không thể chỉ thay đổi tất cả các API hiện tại thành các phần không đồng bộ, vì điều đó sẽ phá vỡ mọi thứ cho khách hàng hiện tại. Tất cả các câu lệnh #if này làm cho mã hoàn toàn dễ đọc hơn một chút. –
Tôi tìm thấy _idea_ của async/await khá hấp dẫn và hợp lý. Tuy nhiên, việc thực hiện thực tế mà Microsoft cung cấp là rắc rối tôi nghĩ. Thực tế là ngữ nghĩa của các cấu trúc này phụ thuộc vào ngữ cảnh trong đó chuỗi được bắt đầu là một sai lầm mà tôi nghĩ. Chủ yếu là vì ngữ nghĩa của mã chương trình nên phụ thuộc vào ngữ cảnh thời gian chạy càng ít càng tốt (khó có thể giải thích được). Tôi có thể hiểu rằng Microsoft muốn thêm các tùy chọn, nhưng tôi nghĩ rằng việc sử dụng đơn giản chờ đợi và đồng bộ không nên đưa ra những khác biệt như vậy. –