5

Tôi đang cố gắng tìm hiểu về SynchronizationContext và bạn bè. Nếu tôi đặt ngữ cảnh đồng bộ hóa tùy chỉnh ở đầu, ví dụ: một ứng dụng giao diện điều khiển. Trong điều kiện nào thì ngữ cảnh đồng bộ hóa hiện tại sẽ hoạt động với các hoạt động không đồng bộ của tôi? Có sự khác biệt giữa Task và các điểm khác, ví dụ: Delegate.BeginInvoke?Đồng bộ hóaTiếp theo, khi nào dòng chảy và khi nào thì không?

void Main() 
{ 
    SynchronizationContext.SetSynchronizationContext(new FooContext()); 
    Action a =() => 
    { 
     var current = SynchronizationContext.Current; 
     //current is null here 
    }; 
    a.BeginInvoke(null,null); 

    ...sleep 

Nếu tôi thực thi nội dung trên nhóm chủ đề, tôi có phải gán ngữ cảnh đồng bộ cho chủ đề cụ thể hiện đang thực thi tác phẩm của mình không?

+1

Hãy xem bài viết này http://msdn.microsoft.com/en-us/magazine/gg598924.aspx. Nhưng một vấn đề là mã khác có thể chọn để ngăn chặn SynchronisationContext được "chảy" bằng cách gọi '.ConfigureAwait (false)'. Thật vậy đó là thực hành tốt nhất cho các thư viện không phải UI để làm điều này, vì chúng ** không ** quan tâm rằng nếu 'await' hồ sơ trên cùng một luồng được bắt đầu. –

+1

Đó là một câu hỏi không thể tin được. Chỉ có cách bạn sẽ nhận được một nơi nào đó với điều này là unwearning rằng một phương thức BeginInvoke() của delegate có * bất cứ điều gì * để làm với SynchronizationContext."BeginInvoke" chỉ là một tên chung cho "chạy mã không đồng bộ". SynchronizationContext chỉ có một cái gì đó để làm với việc phải giải quyết các loại vấn đề bạn chạy vào khi bạn làm điều đó. –

+0

Có thể trả lời giải thích tại sao nó quá rộng? Rất nhiều tài liệu trên mạng làm cho người ta tin rằng bối cảnh đồng bộ hóa sẽ chạy với bối cảnh thực thi giữa các hoạt động không đồng bộ. như trong ví dụ trên, luồng ngữ cảnh logic gọi nhưng không phải bối cảnh đồng bộ hóa. bất kỳ gợi ý nào về lý do tại sao đây là trường hợp thú vị. –

Trả lời

4

Trong điều kiện nào thì ngữ cảnh đồng bộ hóa hiện tại sẽ hoạt động với các hoạt động không đồng bộ của tôi?

Khi một phương pháp async thực hiện một await, theo mặc định nó sẽ chụp một bối cảnh hiện nay và sử dụng để tiếp tục phương pháp async. Ngữ cảnh này là SynchronizationContext.Current trừ khi nó là null, trong trường hợp này là TaskScheduler.Current. Tôi mô tả hành vi này trong số async intro blog post, số MSDN article on SynchronizationContextMSDN article on async best practices của tôi.

Có sự khác biệt giữa Công việc và những người khác, ví dụ: Delegate.BeginInvoke?

Hành vi này là duy nhất cho asyncawait. Delegate.BeginInvoke có nghĩa là "chạy đại biểu này trên một chủ đề hồ bơi thread", vì vậy nó không tuyên truyền các SynchronizationContext. Không thực hiện các cách tiếp cận hiện đại hơn như Task.Run.

Nếu tôi thực thi nội dung trên nhóm chủ đề, tôi có bị buộc gán ngữ cảnh đồng bộ cho chủ đề cụ thể hiện đang thực thi tác phẩm của mình không?

Nói chung, bạn không nên cài đặt ngữ cảnh đồng bộ hóa trên chuỗi mà bạn không sở hữu. Nếu bạn đặt một cái trên một thread thread thread, nó phải được loại bỏ trước khi thread được trả về pool thread. Nhiều khả năng, nếu bạn đang cài đặt một bối cảnh đồng bộ hóa, bạn chỉ cần không bao giờ trả lại luồng (một bối cảnh đồng bộ hóa tùy chỉnh thường được liên kết với một "vòng lặp chính" cho chuỗi đó).

trong ví dụ trên, luồng ngữ cảnh hợp lý nhưng không phải bối cảnh đồng bộ hóa. bất kỳ gợi ý nào về lý do tại sao đây là trường hợp thú vị.

Các ngữ cảnh khác thậm chí còn ít tài liệu hơn. Stephen Toub có số definitive post on the subject. Về bản chất, một số dữ liệu như bảo mật phải là dòng; hầu hết các dữ liệu khác không.

Các vấn đề liên quan