Xem xét phương thức Socket.BeginSend()
. Nếu hai thread thread thread được gọi phương thức này cùng một lúc, liệu các thông điệp tương ứng của chúng có kết thúc với nhau hay không, lớp socket giữ cho điều này xảy ra?Có phải không đồng bộ ghi vào một ổ cắm an toàn không?
Trả lời
Tôi đã tìm thấy một số post on the MSDN forum quen thuộc dường như trả lời cho câu hỏi của bạn.
- Bạn có thể xếp hàng nhiều BeginSends cùng một lúc. Bạn không cần phải khóa
Edit:
thông tin Thậm chí thú vị hơn:
Nếu bạn cuộn xuống một chút trong Remark section of the MSDN doc BeginSend(), bạn sẽ tìm thấy sử dụng thú vị của callback các phương pháp có thể phù hợp với bạn.
[...] Nếu bạn muốn chuỗi ban đầu chặn sau khi bạn gọi phương thức BeginSend, hãy sử dụng phương thức WaitHandle.WaitOne. [...]
Tôi không biết điều này, cảm ơn! – covertCoder
Đây chính xác là những gì tôi đang tìm kiếm! CẢM ƠN! – Dabloons
Trường hợp ổ cắm .NET không an toàn chỉ trong các cuộc gọi đồng thời tới một số phương thức (cùng hoặc các phương thức khác) có thể gây ra trạng thái không nhất quán. Tuy nhiên, các phương pháp BeginSend()
và BeginReceive()
an toàn theo chủ đề đối với chính chúng.
Có thể thực hiện nhiều cuộc gọi chưa thực hiện cho mỗi (hoặc cả hai).
Trong trường hợp BeginReceive()
, chúng sẽ được bảo dưỡng khi dữ liệu có sẵn theo thứ tự được gọi. Điều này có thể hữu ích nếu, ví dụ, xử lý của bạn là dài nhưng bạn muốn nhận được khác xảy ra càng nhanh càng tốt. Tất nhiên trong trường hợp này bạn có thể có mã của bạn xử lý nhiều biên lai cùng một lúc và bạn có thể cần logic đồng bộ hóa của riêng bạn để bảo vệ trạng thái ứng dụng của bạn.
Trong trường hợp BeginSend()
, mỗi cuộc gọi sẽ cố đẩy dữ liệu đã gửi vào bộ đệm ổ cắm và ngay khi được chấp nhận ở đó, cuộc gọi lại của bạn sẽ được gọi (nơi bạn sẽ gọi EndSend()
). Nếu không có đủ dung lượng bộ đệm cho bất kỳ cuộc gọi nào, nó sẽ chặn.
Lưu ý: đừng cho rằng bộ đệm mặc định 8k có nghĩa là "tôi có thể nhanh chóng gọi BeginSend()
với chính xác 8k dữ liệu, sau đó nó sẽ chặn", như sau đây là đúng:
Các 8K là một "kích thước danh nghĩa" số, và bộ đệm có thể co lại và phát triển hơi
Khi bạn đang queing lên đáng 8K cuộc gọi, dữ liệu sẽ được được gửi trên mạng giảm mà 8K dữ liệu xếp hàng đợi
Nói chung:
Nếu bạn gọi
BeginSend()
nhiều lần trong một chủ đề, bạn được đảm bảo rằng sẽ gửi sẽ rời khỏi máy theo thứ tự chúng được gọi.Nếu bạn gọi
BeginSend()
từ một số chủ đề, không đảm bảo đơn đặt hàng trừ khi bạn sử dụng một số cơ chế chặn khác để buộc các cuộc gọi thực sự xảy ra theo một số thứ tự cụ thể. Tuy nhiên, mỗi cuộc gọi sẽ gửi dữ liệu của nó đúng trong một luồng byte liền kề.
Câu trả lời của bạn đã đến một vài năm sau câu hỏi ban đầu và tôi vừa mới thấy nó (một năm sau) nhưng tôi muốn bạn biết rằng nó có chi tiết tuyệt vời và tôi thực sự đánh giá cao nó. Mặc dù, kiến thức cá nhân của riêng tôi về khuôn khổ .Net và kỹ năng của tôi là một nhà phát triển đã vượt qua câu hỏi này ngay bây giờ, câu trả lời này sẽ là một nguồn tài nguyên tuyệt vời cho người đọc trong tương lai. Nếu tôi chưa kiểm tra câu trả lời đúng như câu trả lời đúng năm trước, tôi sẽ trả lời đúng cho bạn. Nhiều đánh giá cao. – Dabloons
- 1. Có thể ghi vào ổ cắm UDP bao giờ không?
- 2. Chủ đề chức năng đọc và ghi ổ cắm có an toàn không?
- 3. Ổ cắm Lua - Sự kiện không đồng bộ
- 4. Tạo chuỗiWithContentsOfURL không đồng bộ - Có an toàn không?
- 5. Ổ cắm I/O không đồng bộ trên Android
- 6. java.lang.Thread có phải là một lớp an toàn không?
- 7. Có phải SecurityContextChủ đề an toàn không?
- 8. close() cắm trực tiếp sau khi gửi(): không an toàn?
- 9. Sử dụng C++ 11 lambdas không đồng bộ, an toàn
- 10. Việc đóng luồng đầu vào của ổ cắm cũng có đóng kết nối ổ cắm không?
- 11. DWScript có an toàn không?
- 12. Điều gì cấu thành sự an toàn không đồng bộ
- 13. Có phải đọc đồng thời từ một chuỗi an toàn không?
- 14. NSTimer có phải là chủ đề an toàn không?
- 15. Có phải Azure CloudTable là chủ đề an toàn không?
- 16. Có an toàn để tạo một FileInfo trên một tệp hiện đang được ghi vào không?
- 17. Ổ cắm có thể được đóng từ một sợi khác khi gửi/recv trên cùng một ổ cắm không?
- 18. Truy cập đọc đồng thời trên một mảng int []: Có an toàn không? Có nhanh không?
- 19. Có an toàn khi gọi phương thức được đồng bộ từ một phương thức được đồng bộ khác không?
- 20. Ổ cắm máy khách không đồng bộ hướng dẫn sử dụngResetEvent đang thực hiện
- 21. .NET Socket Send()/Receive() có an toàn không?
- 22. Có phải chuỗi được tạo ra Axis2 an toàn không?
- 23. Luồng có an toàn không?
- 24. Bạn có thể ghi vào luồng đầu vào và đầu ra của ổ cắm cùng một lúc không?
- 25. C socket API có an toàn không?
- 26. Có an toàn khi kết nối NetworkStream với BufferedStream để đọc không đồng bộ không?
- 27. Làm cách nào tôi có thể cấu hình một cách an toàn các ổ cắm AppEngine với Google Compute Engine
- 28. Chủ đề java.util.Hashtable có an toàn không?
- 29. Ổ cắm có đáng tin cậy không?
- 30. Có cần phải đăng ký lại một ổ cắm từ epoll trước khi đóng nó không?
Trong khi nó hoạt động, bạn chỉ nên thực hiện với giao thức dựa trên datagram đặt hàng không đáng tin cậy như UDP. Lý do là nếu hai chủ đề chạy đua để gọi BeginSend, bạn có thể nhận được ra lệnh gửi tại nguồn. Điều này sẽ dẫn đến hỏng dữ liệu ứng dụng khi sử dụng TCP. –