2012-02-23 31 views
16

Tôi luôn thấy mọi người đang sử dụng Thread.Sleep() để tạo sự chậm trễ trong quá trình xử lý hoặc điều gì đó tương tự và mọi người luôn bị bắt buộc phải sử dụng theo cách này.Khi nào thì sử dụng Thread.Sleep() hợp lý?

Khi nào hợp lý/bắt buộc phải sử dụng Thread.Sleep()?

+0

Tại sao mọi người lại bỏ phiếu cho câu hỏi này mà không có bất kỳ giải thích nào về lý do tại sao? – ediblecode

+0

-1 Vui lòng chọn một ngôn ngữ. Câu trả lời cho câu hỏi này sẽ tham khảo các thư viện khác. Thật khó hiểu khi đặt câu hỏi này về hai ngôn ngữ khác nhau cùng một lúc. –

+1

@ErickRobertson Vì vậy, bạn có nói rằng hai câu hỏi nên được tạo ra? Có vẻ hơi không quan trọng với tôi. – ediblecode

Trả lời

22

Bạn nên gọi Thread.sleep() khi bạn thực sự cần sự chậm trễ trong chuỗi nền.

Không gọi nó để giúp đồng bộ hóa (nó sẽ không), không gọi nó trong một vòng lặp để chờ đợi một cái gì đó (nó sẽ được làm chậm) và không bao giờ gọi nó trên một chủ đề giao diện người dùng (nó sẽ đóng băng).

+10

Chỉ cần thêm: Và không cố gắng để xây dựng một bộ đếm thời gian chính xác với Thread.Sleep hoặc. –

+0

Tôi sử dụng 'Thread.Sleep' trên một chuỗi nền trong khi thực hiện xử lý lâu trên một tập hợp các tập tin hoặc một ổ cắm mạng (và thực hiện một cuộc gọi lại khi thread được hoàn thành). Đây có phải là một sử dụng tốt cho 'Thread.Sleep' hoặc là có một machanism tốt hơn để làm điều này? – Matthew

+0

@Matthew Âm thanh giống như bạn có thể đang sử dụng hai luồng để thực hiện công việc của một sợi chỉ. Chủ đề ngủ có làm bất cứ điều gì ngoài việc định kỳ thức dậy và kiểm tra xem liệu một chuỗi công nhân vẫn đang hoạt động? Chuỗi công nhân không thể gọi chính cuộc gọi lại khi nó được thực hiện? –

-2

nếu bạn muốn một chủ đề ngừng làm điều gì đó, đôi khi bạn tạo vòng lặp vô tận, bạn không muốn vòng lặp không ngừng, vì nó cũng sẽ mất nhiều năng lượng CPU, thêm một luồng trong đó sẽ làm cho vòng lặp "nghỉ ngơi" và cung cấp cho CPU một số phần còn lại ^^.

+0

Nếu bạn định lập chương trình như vậy, bạn sẽ không Sử dụng bộ đếm thời gian? – ediblecode

+1

Làm thế nào để bạn sử dụng bộ hẹn giờ để thay thế một cuộc gọi sleep()? Giả sử bạn đang ở trong một sự kiện phiên dịch lệnh của bên thứ ba 'OnProcessLine', một chiều sâu không xác định trên ngăn xếp của một vài luồng chạy các tập lệnh khác nhau –

0

Nó có thể được sử dụng để buộc chuyển đổi ngữ cảnh (có tham số 1) hoặc đưa ra các chuỗi ưu tiên cao hơn khác (với số 0) .... nhưng điều đó hiếm khi cần thiết.

5

Khi bạn cần giới thiệu tạm dừng trong một số mã lệnh throwaway hoặc testing, Thread.Sleep() là tốt.

Trong mã sản xuất, cách tốt nhất là cố gắng tìm một tùy chọn khác. Ví dụ: nếu bạn đang cố gắng làm điều gì đó trong một khoảng thời gian, hãy sử dụng một trong nhiều lớp hẹn giờ có sẵn. Nếu bạn đang cố gắng tạm dừng khi hàng đợi đầu vào trống (và bật .NET), hãy cân nhắc sử dụng Monitor.Wait()Monitor.Pulse() để thay thế.

More (một lần nữa, NET-centric) giải thích về những nhược điểm của Sleep() trong bài viết này: Thread.Sleep is a sign of a poorly designed program.

+1

+1 nó có rất nhiều việc sử dụng mã phi sản xuất, nó cũng hữu ích để chứng minh các tác vụ chạy dài khi phát triển/trình diễn các khuôn khổ đa luồng, v.v. biết rằng nó – Servy

+0

Tôi đã đọc bài viết được liên kết trước đó, tôi chỉ đọc lại nó một lần nữa, nó tệ lắm, nó càng tệ hơn lần thứ hai. –

3

Khi viết mã kiểm tra. Nếu bạn muốn xem cách một số hàm xử lý được gọi bởi nhiều luồng một cách ngẫu nhiên.

Ngoài ra, nếu bạn muốn mô phỏng độ trễ để thử nghiệm. Giả sử bạn muốn kiểm tra thanh tiến trình.

3

Có rất ít tình huống mà tôi cho rằng nó có thể chấp nhận được. Cuối cùng nó đi xuống đến các điều kiện sau đây trong tâm trí của tôi- những người khác có thể kêu vang trong trường hợp những điều này không áp dụng, nhưng như một quy tắc chung TẤT CẢ những điều sau đây sẽ cần phải đúng với tôi để sử dụng Thread.Sleep trong sản xuất (đang aka không tầm thường hoặc thử nghiệm):

  1. Bạn đang chờ đợi vào một nguồn tài nguyên
  2. tài nguyên trong câu hỏi không cung cấp thông báo chủ động thích hợp của sự sẵn sàng (một WaitHandle hoặc một cái gì đó)
  3. Bạn có thể không nếu không sửa đổi tài nguyên trong câu hỏi để làm như vậy
  4. Bạn đã đo và biết rằng bạn cần phải chờ đợi đủ lâu để SpinWait không được chứng minh, d rằng bạn nhận được hiệu suất tốt hơn bằng cách rời khỏi ngữ cảnh.
0

Nếu bạn cần Thread.Sleep bạn có thể có thiết kế sai. Các cơ chế đồng bộ hóa sử dụng tốt hơn như AutoResetEvent hoặc ManualResetEvent và chờ các sự kiện xảy ra. Tôi thường thấy Cuộc thăm dò được thực hiện với Thread.Sleep nhưng tốt hơn là nên thử sử dụng các sự kiện nếu có thể.

+1

Câu trả lời này cung cấp không có câu trả lời cho câu hỏi. – ediblecode

+0

Tôi muốn nói với bạn rằng bạn không bao giờ nên sử dụng Thread.Sleep và cơ chế sự kiện sử dụng tốt hơn. Đó là câu trả lời của tôi cho câu hỏi của bạn, có lẽ nó không rõ ràng. – BlueM

+0

Và như đã đề cập trong câu trả lời ở trên trong http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx nó thực sự là một dấu hiệu của thiết kế xấu. "Trong .NET không có lý do nào khác để sử dụng nó." – BlueM

0

Khiếu nại về việc sử dụng chế độ ngủ thường liên quan đến thiết kế đa luồng hiệu quả (hoặc không hiệu quả).Đa luồng là một chủ đề rất lớn, và tôi chỉ đơn giản giới thiệu cho bạn một cuốn sách hay về nó (Java Concurrency in Practice by Goetz).

Nếu bạn muốn trì hoãn mã xử lý của mình trong một khoảng thời gian cố định, thì sleep() là một điều tốt (tuy nhiên, lớp Timer là cách hay để thực hiện hành vi định kỳ).

+0

Bộ tính giờ buộc các nhà phát triển phát triển các máy trạng thái để thực hiện các thông số kỹ thuật theo thủ tục. Nếu một thao tác được xác định bởi các chuỗi các giai đoạn đơn giản hơn, thường được phân tách bằng các khoảng thời gian dài, các cuộc gọi hàm và sleep() sẽ gọi trực tiếp đến bản đồ này. Một máy trạng thái không đồng bộ thì không. –

+0

'Khiếu nại về việc sử dụng giấc ngủ thường liên quan đến thiết kế đa luồng hiệu quả (hoặc không hiệu quả).' Điều này là rất đúng nhưng, thật đáng buồn, điều này dịch trong một số tâm trí vào 'Sleep() là một anti-pattern'. 'Hàng năm, những người đấu thầu lửa, xe cứu thương và tàu tuần dương cảnh sát gây ra hàng trăm vụ tai nạn giao thông - do đó tất cả họ đều bị cấm'. –

-1

Sử dụng nó bất cứ khi nào bạn cần tạm dừng trong hoạt động của mình. Nếu spec nói 'bây giờ chờ ít nhất 10 giây trước khi tiếp tục', sau đó gọi sleep (10000). Có một giải pháp thay thế - bạn có thể viết lại mã của mình dưới dạng công cụ trạng thái để kiểm soát có thể được đầu hàng cho đến khi một sự kiện hẹn giờ được kích hoạt vào nó. Một máy trạng thái bảng điều khiển rất linh hoạt và cho phép hoạt động hoàn toàn không đồng bộ. Kết quả 'mã' có thể sẽ không giống với spec yêu cầu trong bất kỳ cách nào, nó gần như không thể hiểu những gì đang xảy ra, khó gỡ lỗi và một cơn ác mộng để sửa đổi, duy trì và/hoặc enchance, nhưng bạn sẽ có thể tránh được , gọi điện thoại 'Sleep (10000)'.

Khi những người khác đã đăng, không sử dụng nó cho các chủ đề liên ren! Tất cả các hệ điều hành đa nhiệm đều có nhiều cơ chế sychro hiệu quả hơn.

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