Theo sau từ câu hỏi BeginInvoke()/EndInvoke() của tôi, có sự khác biệt lớn về hiệu suất/bất kỳ thứ gì khác giữa Đại biểu. BeginInvoke() và sử dụng QueueUserWorkItem() để gọi một delegate không đồng bộ?Sự khác nhau giữa QueueUserWorkItem() và BeginInvoke(), để thực hiện một hoạt động không đồng bộ không có kiểu trả về là cần thiết
Trả lời
http://blogs.msdn.com/cbrumme/archive/2003/07/14/51495.aspx
nói:
"Một thực tế đáng ngạc nhiên là điều này là cũng tại sao Delegate.BeginInvoke/ EndInvoke đang quá chậm so với kỹ thuật tương đương như ThreadPool.QueueUserWorkItem (hoặc UnsafeQueueUserWorkItem nếu bạn hiểu ý nghĩa bảo mật và muốn thực sự hiệu quả) .Mã số cho BeginInv oke/EndInvoke nhanh chóng biến thành mã thông báo thông báo chung của lộ trình từ xa chung . "
Hmmm, cảm ơn, đó là cả hai thú vị và rất đáng sợ. Tôi nghĩ rằng tôi sẽ quay trở lại bất kỳ BeginInvoke()/EndInvoke() mã mà không yêu cầu giá trị trả lại! – endian
Điều quan trọng tôi có thể nghĩ đến với QueueUserWorkItem
là bạn phải sử dụng các loại WaitCallback
đại biểu, trong đó trông phức tạp nếu bạn đã có một trường hợp SomeRandomDelegate
và một số args. Tin tốt là bạn có thể sửa lỗi này với một kết thúc:
ThreadPool.QueueUserWorkItem(
delegate { someDelegate(arg1, arg2); }
);
mô hình này cũng đảm bảo bạn sẽ có được gõ mạnh thích hợp tại thời gian biên dịch (không giống như đi qua một arg object
nhà nước để QueueUserWorkItem
và đúc nó trong phương pháp mục tiêu). Mô hình này cũng có thể được sử dụng khi gọi phương pháp trực tiếp:
ThreadPool.QueueUserWorkItem(
delegate { SomeMethod(arg1, arg2); }
);
Rõ ràng, không có EndInvoke
tương đương, bạn cũng không thể có được một giá trị trả lại ra trừ khi bạn gọi một phương thức/nâng cao một sự kiện/etc ở cuối của phương pháp của bạn ... trên một lưu ý liên quan, bạn cần phải cẩn thận với exception handling.
Gặp phải tình huống chính xác này là lần đầu tiên tôi tự nghĩ, "Wow, tôi yêu đóng cửa. " –
Wow, đây là một mẹo cực kỳ. Nó cảm thấy như một ngữ nghĩa boxing/unboxing, và tôi tưởng tượng không tốn kém hơn, trong một kế hoạch rộng lớn của sự vật. –
Rất tiếc, về mặt kỹ thuật, nó phải là "đại biểu (đối tượng o)" hoặc tương tự để mã biên dịch, tôi tin rằng, vì QueueUserWorkItem mong đợi chữ ký ủy nhiệm khớp với WaitCallback, tức là một chữ bao gồm một tham số duy nhất của đối tượng kiểu. –
Không nên có bất kỳ sự khác biệt lớn nào, tôi cũng nghĩ rằng BeginInvoke/EndInvoke được tạo cho một đại biểu sử dụng nhóm luồng để thực thi.
Không được có bất kỳ sự khác biệt về hiệu suất nào, vì cả Delegate.BeginInvoke và ThreadPool.QueueUserWorkItem sẽ thực thi trên một chuỗi chủ đề chuỗi.
Sự khác biệt lớn nhất là nếu bạn gọi BeginInvoke, bạn bắt buộc phải gọi EndInvoke tại một số điểm. Ngược lại, ThreadPool.QueueUserWorkItem là "lửa và quên". Điều đó có lợi ích và hạn chế. Lợi ích là bạn có thể quên nó. Hạn chế là bạn không có cách nào để biết, trừ khi bạn thêm cơ chế đồng bộ/thông báo của riêng mình, khi tác vụ đã hoàn thành.
EndInvoke() có hành vi hữu ích nhưng ít được đề cập - nó trả về tất cả các ngoại lệ chưa được giải quyết mà đại biểu được tạo trong ngữ cảnh của chuỗi ban đầu để bạn có thể di chuyển logic xử lý ngoại lệ vào mã chính.
Ngoài ra, nếu đại biểu của bạn có tham số out/ref, chúng sẽ được thêm vào chữ ký EndInvoke() cho phép bạn lấy chúng khi phương thức hoàn thành thực thi.
cảm ơn rất nhiều, tôi không biết rằng – endian
Nếu bạn gọi ThreadPool.QueueUserWorkItem, các ngoại lệ được nêu ra trong mục công việc sẽ được giải phóng trên luồng nền (trừ khi bạn bắt chúng một cách rõ ràng). Trong .Net 2 và cao hơn điều này sẽ chấm dứt AppDomain của bạn.
Nếu bạn gọi delegate.BeginInvoke() thì ngoại lệ sẽ được xếp hàng đợi để được ném lại khi EndInvoke() được gọi. Nếu bạn không bao giờ gọi EndInvoke(), thì các ngoại lệ về cơ bản là bộ nhớ 'bị rò rỉ' (như bất kỳ trạng thái nào khác không được giải phóng bởi hoạt động async).
- 1. Sự khác nhau giữa chặn với đồng bộ, không chặn và không đồng bộ là gì?
- 2. Sự khác biệt giữa Gọi() và BeginInvoke()
- 3. Có sự khác nhau giữa hàm có và không có câu lệnh trả về không?
- 4. Sự khác biệt giữa InvokeAsync và BeginInvoke cho WPF Dispatcher
- 5. Sự khác nhau giữa e.preventDefault(); và trả về false?
- 6. CDATA có thực sự cần thiết không?
- 7. sự khác nhau giữa hai cuộc gọi không đồng bộ này trong EF là gì?
- 8. Sự khác nhau giữa phương thức được đồng bộ hóa và khối đồng bộ trong Java là gì?
- 9. .NET ThreadPool QueueUserWorkItem Đồng bộ hóa
- 10. Có cần thiết một tin nhắn đại biểu phải luôn luôn có hiệu lực như một kiểu trả về không?
- 11. Sự khác nhau giữa SyncML và CalDAV là gì?
- 12. Sự khác biệt giữa gmake và thực hiện là gì?
- 13. KillTimer có thực sự cần thiết không?
- 14. Sự khác nhau giữa các tùy chọn đồng bộ luồng khác nhau trong C# là gì?
- 15. Hoạt động đồng bộ và không đồng bộ
- 16. sự khác biệt giữa các phương pháp JVM không đồng bộ đồng bộ và
- 17. Sự khác nhau giữa việc thực hiện Giao diện trong Delphi và Lazarus (FPC) là gì?
- 18. Sự khác nhau giữa ConfigurationManager.GetSection và Configuration.GetSection là gì?
- 19. Có thể có các kiểu trả về khác nhau cho một phương thức quá tải không?
- 20. Sự khác nhau giữa động và System.Object
- 21. Sự khác nhau giữa UPnP AV và DLNA là gì?
- 22. Sự khác nhau giữa Request.Url.Query và Request.QueryString là gì?
- 23. Sự khác nhau giữa thư đang chờ và không đồng bộ và thư viện Task song song
- 24. Sự khác nhau giữa Phing và PHPUnderControl là gì?
- 25. Sự khác nhau giữa `ImmutableSortedSet` và fsharp` Set` là gì?
- 26. Trong C# .NET, thực hiện thao tác không đồng bộ có nhất thiết phải tạo một chuỗi chặn không?
- 27. Sự khác nhau giữa LinFu.DynamicProxy và Castle.DynamicProxy là gì?
- 28. SqlBulkCopy: Sự khác nhau giữa việc truyền SqlBulkCopyOptions.UseInternalTransaction và không vượt qua nó là gì?
- 29. Sự khác nhau giữa dict() và {} là gì?
- 30. VIM: Sự khác nhau giữa bộ và setl trong quan điểm về filetype
Bạn cũng có thể muốn xem: http://marcgravell.blogspot.com/2009/02/async-without-pain.html –