2012-03-05 28 views
9

Tôi hiểu rằng trong dịch vụ Windows, tốt hơn nên sử dụng Timer thay vì Thread.Sleep(timeout). Tuy nhiên, trong tất cả các ví dụ mã tôi có thể tìm thấy trên Internet đã xử lý công nhân Azure, nó là Thread.Sleep(timeout) được sử dụng thay vì Timer.Sử dụng Thread.Sleep hoặc Timer trong vai trò nhân viên Azure trong .NET?

Ngay cả những mã mặc định được cung cấp trong mẫu dự án Worker trong Visual Studio sử dụng một Thread.Sleep:

public class WorkerRole : RoleEntryPoint 
{ 
    public override void Run() 
    { 
     // This is a sample worker implementation. Replace with your logic. 
     Trace.WriteLine("$projectname$ entry point called", "Information"); 

     while (true) 
     { 
      Thread.Sleep(10000); 
      Trace.WriteLine("Working", "Information"); 
     } 
    } 
// ... 
} 

Cho đến nay, tôi đã được sử dụng cũng Thread.Sleep ở công nhân của tôi, nhưng mà không thực sự hiểu tại sao. Vì vậy, câu hỏi của tôi là, tại sao sử dụng Thread.Sleep(timeout) trong vai trò người lao động Azure thay vì Timer? Sự khác nhau giữa dịch vụ Windows và nhân viên Azure dẫn đến sự khác biệt này trong cách chúng ta được cho là thụ thai loại ứng dụng này là gì? Có tốt hay xấu khi sử dụng Timer trong công nhân Azure?

Bất kỳ lời giải thích nào có liên kết đến một số tài nguyên giải thích nguyên tắc cơ bản của điều này đều được chào đón vì tôi không thể tìm thấy bất kỳ điều gì cho đến thời điểm này.

+0

Đây không thực sự là câu hỏi cụ thể cho Windows Azure. Có một [câu trả lời tuyệt vời của StackOverflow] (http://stackoverflow.com/questions/2822441/system-timers-timer-threading-timer-vs-thread-with-whileloop-thread-sleep-for) có một chút chi tiết về các bộ tính giờ khác nhau. Điều này cũng áp dụng cho các máy ảo Windows Azure, vì chúng là các máy ảo Windows Server 2008. –

+0

Cảm ơn bạn đã liên kết. Thật thú vị nhưng tôi không cảm thấy nó thực sự trả lời câu hỏi của tôi. Tôi hiểu Windows Azure là máy ảo nhưng nếu nó là _just_ VM, tại sao không chỉ sử dụng Windows Services? Trong trường hợp đó, câu hỏi của tôi sẽ không cần thiết. – Guillaume

+0

Ah ... Vâng, bạn chắc chắn có thể sử dụng Windows Services. Tuy nhiên, để sử dụng Dịch vụ Windows trong Windows Azure, bạn sẽ cần thực hiện một số công việc. Đây là [bài đăng blog] (http://blogs.msdn.com/b/mwasham/archive/2011/03/30/migrating-a-windows-service-to-windows-azure.aspx) cho biết những gì có liên quan. Nó đơn giản hơn nhiều để chạy mã của bạn trong các sự kiện được cung cấp bởi Windows Azure Worker hoặc Web Role. Xem [trả lời về điều này] của tôi (http://serverfault.com/a/365054/99269) trên ServerFault là tốt. –

Trả lời

15

Mục đích của vòng lặp Thread.Sleep() là giữ phương thức Run() thoát khỏi. Nếu số Run() thoát, thì nhân viên của bạn sẽ khởi động lại. Tôi không biết rằng bạn có thể hoàn thành mục tiêu đó một cách hiệu quả với Bộ hẹn giờ.

Rất có thể CPU của bạn đang lãng phí một lượng thời gian nhỏ để đánh thức chuỗi đó mỗi 1000 mili giây để không làm gì cả. Tôi nghi ngờ nó có ý nghĩa, nhưng nó cũng làm tôi buồn. Giải pháp của tôi là chờ một CancellationToken thay thế.

public class WorkerRole : RoleEntryPoint { 
    CancellationTokenSource cancelSource = new CancellationTokenSource(); 

    public override void Run() 
    { 
     //do stuff 
     cancelSource.Token.WaitHandle.WaitOne(); 
    } 

    public override void OnStop() 
    { 
     cancelSource.Cancel(); 
    } 
} 

Điều này giữ cho phương thức Run() thoát mà không lãng phí thời gian CPU chờ đợi bận. Bạn cũng có thể sử dụng CancellationToken ở nơi khác trong chương trình của mình để bắt đầu bất kỳ thao tác tắt máy nào khác mà bạn có thể cần thực hiện.

+0

Bạn có nghĩa là ngay cả khi tôi có Bộ hẹn giờ được đặt làm trường tĩnh của lớp 'WorkerRole' của tôi và sự kiện' Elapsed' của nó có một phương thức được gán cho nó, luồng vẫn sẽ thoát khi phương thức 'Run()' được xử lý ? – Guillaume

+1

Vâng, đó là những gì tài liệu nói. Nếu bạn thử nó, bạn sẽ rất có thể thấy vai trò của bạn liên tục khởi động, tắt máy và khởi động lại. http://msdn.microsoft.com/en-us/library/windowsazure/microsoft.windowsazure.serviceruntime.roleentrypoint.run.aspx –

+2

Giải pháp 'Thread.Sleep (Timeout.Infinity)' xếp chồng lên nhau như thế nào khi chờ đợi trên 'WaitHandle'? Và vì lý do đó, tại sao không chỉ sử dụng 'ManualResetEvent'? Đó là nhiều hơn khả năng cùng một điều. – casperOne

-2

Thread.Sleep có nghĩa là lãng phí thời gian của bộ xử lý của bạn. Chủ đề của bạn bị chặn và mặc dù CPU không làm gì nhưng nó không thể được sử dụng bởi các luồng khác. Tôi không quen với mô hình định giá của Azure, nhưng bạn có thể bị tính phí trong thời gian này, vì chuỗi của bạn đã sử dụng nó :)

Vì vậy, luôn luôn sử dụng bất kỳ loại tạm dừng nào.

Ví dụ về mã thường sử dụng Thread.Sleep để đơn giản.

+0

M $ phí cho việc không làm gì cả? Tuyệt vời - Tôi ước mình có thể thoát khỏi điều đó! –

+7

@Martin - Microsoft tính phí sử dụng tài nguyên. Bạn có thể chạy máy ảo của mình ở mức 0% hoặc 100% CPU suốt cả ngày - cuộc gọi của bạn. Bạn trả cho mỗi lõi mỗi giờ. Cũng giống như thuê một phòng khách sạn: Bạn trả tiền cho dù bạn đang ở trong đó ném một bữa tiệc hoặc đi từ nó tham quan. –

+0

Thực tế, không chỉ các ví dụ mã mà tôi thấy là sử dụng 'Thread.Sleep'. Ngay cả mã mặc định được cung cấp bởi mẫu Worker khi bạn tạo một dự án Worker mới sử dụng 'Thread.Sleep'. – Guillaume

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