2009-07-01 30 views
10

Tôi cần phải thực hiện một loại "hết giờ" hoặc tạm dừng trong phương pháp của tôi trong 10 giây (10000 mili giây), nhưng tôi không chắc liệu những điều sau đây có hoạt động như tôi không có đa luồng.Tạm dừng phương thức để đặt # mili giây

Thread.Sleep(10000); 

tôi sẽ cố gắng sử dụng mã hiện tại, nhưng tôi sẽ đánh giá cao nếu ai đó có thể giải thích một cách tốt nhất và chính xác để làm điều này, đặc biệt là nếu mã ở trên không hoạt động đúng. Cảm ơn!

CẬP NHẬT: Chương trình này thực sự là một ứng dụng giao diện điều khiển trong chức năng đang được hỏi đang thực hiện nhiều HTTPWebRequests cho một máy chủ, vì vậy tôi muốn trì hoãn chúng trong một số mili giây được chỉ định. Do đó, không cần gọi lại - tất cả những gì cần là một "tạm ngưng vô điều kiện" - về cơ bản chỉ toàn bộ điều dừng lại trong 10 giây và sau đó tiếp tục đi. Tôi hài lòng rằng C# vẫn coi đây là một chủ đề, vì vậy Thread.Sleep (...) sẽ hoạt động. Cảm ơn tất cả mọi người!

+0

Đây có phải là ứng dụng Windows Forms không? – Groo

+0

Tôi đã cập nhật bài đăng để làm rõ bản chất của ứng dụng. –

Trả lời

12

Bạn có thể không có đa luồng, nhưng bạn vẫn đang thực hiện trong một chuỗi: tất cả mã thực thi trong một chuỗi.

Gọi Thread.Sleep thực sự sẽ tạm dừng luồng hiện tại. Bạn có thực sự muốn nó tạm dừng vô điều kiện trong 10 giây, hay bạn muốn có thể bị "đánh thức" bởi cái gì khác đang xảy ra? Nếu bạn chỉ thực sự sử dụng một chuỗi, hãy gọi Sleep cũng có thể là cách tốt nhất để chuyển tiếp, nhưng nó sẽ phụ thuộc vào tình huống.

Cụ thể, nếu bạn đang viết ứng dụng GUI, không muốn sử dụng Thread.Sleep từ chuỗi giao diện người dùng, nếu không toàn bộ ứng dụng của bạn sẽ không phản hồi trong 10 giây.

Nếu bạn có thể cung cấp thêm thông tin về đơn đăng ký của mình, điều đó sẽ giúp chúng tôi tư vấn cho bạn tốt hơn.

+1

Ứng dụng của tôi thực sự là một ứng dụng giao diện điều khiển đang tạo một lượng lớn yêu cầu HTTP tới một máy chủ vì vậy tôi không muốn áp đảo nó và tạm dừng giữa các lô 4 hoặc lâu hơn đã tạm dừng tự động, nhưng không có mã như vậy. Có, tôi đã hy vọng rằng C# vẫn nhận ra đây là một chủ đề nên cảm ơn bạn! –

1

Có, điều đó chỉ hoạt động tốt.

Bạn không cần phải có nhiều luồng để sử dụng một số phương thức trong lớp Thread. Bạn luôn có ít nhất một luồng.

3

Điều đó thực sự sẽ tạm dừng chuỗi/phương pháp thi hành trong 10 giây. Bạn có thấy một vấn đề cụ thể không?

Lưu ý rằng bạn không nên Sleep chuỗi giao diện người dùng - tốt hơn nên thực hiện gọi lại thay thế.

Cũng lưu ý rằng có nhiều cách khác để chặn luồng cho phép truy cập đơn giản hơn để làm cho nó hoạt động trở lại (nếu bạn thấy nó OK sau 2 giây); như Monitor.Wait(obj, 10000) (cho phép một thread để Pulse nếu cần thiết để đánh thức nó lên):

static void Main() { 
    object lockObj = new object(); 
    lock (lockObj) { 
     new Thread(GetInput).Start(lockObj); 
     Monitor.Wait(lockObj, 10000); 
    } 
    Console.WriteLine("Main exiting"); 
} 
static void GetInput(object state) { 
    Console.WriteLine("press return..."); 
    string s = Console.ReadLine(); 
    lock (state) { 
     Monitor.Pulse(state); 
    } 
    Console.WriteLine("GetInput exiting"); 
} 

Bạn có thể làm điều này với Thread.Interrupt quá, nhưng IMO đó là Messier.

+0

Cảm ơn bạn đã cho các mẹo! –

0

Để hết thời gian chờ, bạn nên có trường boolean biến động tĩnh isRunning. Khi chuỗi mới bắt đầu, isRunning phải trở thành true và cuối cùng phải trở thành false.

Chuỗi chính phải có phương thức lặp cho isRunning trong thời gian chờ bạn xác định. Khi thời gian chờ kết thúc, bạn nên thực hiện logic. Tuy nhiên, không bao giờ sử dụng phương pháp hủy bỏ thread.

Tạm dừng ...không có một giải pháp đơn giản. Nó phụ thuộc vào những gì bạn đang làm bên trong luồng. Tuy nhiên, bạn có thể xem Monitor.Wait.

1

Thread.Sleep là tốt và AFAIK theo cách phù hợp. Ngay cả khi bạn không Multithreaded: Luôn luôn có ít nhất một Thread, và nếu bạn gửi rằng để ngủ, nó ngủ.

khác (xấu) cách is a spinlock, một cái gì đó như:

// Do never ever use this 
private void DoNothing(){ } 

private void KillCPU() 
{ 
    DateTime target = DateTime.Now.AddSeconds(10); 
    while(DateTime.Now < target) DoNothing(); 
    DoStuffAfterWaiting10Seconds(); 
} 

này được buồn bã vẫn đang được sử dụng bởi những người và trong khi nó sẽ tạm dừng chương trình của bạn trong 10 giây, nó sẽ chạy ở 100% CPU Sử dụng (Vâng, trên hệ thống Multi-Core nó là một lõi).

+0

Im laffing tại ví dụ đó CPU hogging - sẽ cần phải đặt nó xuống trong cuốn sách của tôi như là một cách cổ điển làm đầy CPU của ai đó! : D cảm ơn cho tip tho! –

+1

'while (DateTime.Now Groo

+0

Rất may là tôi chỉ vô dụng trong các điều khoản của luồng và tất cả những thứ tốt đó - {} tôi hiểu tho. : D –

2

Bạn có thể sử dụng một thread riêng biệt để làm điều đó:

ThreadPool.QueueUserWorkItem(
     delegate(object state) 
     { 
      Thread.Sleep(1000); 
      Console.WriteLine("done"); 
     }); 

Nhưng, nếu đây là một Windows Forms ứng dụng, bạn sẽ cần phải gọi mã sau độ trễ từ sợi Gui (bài viết này , ví dụ: How to update the GUI from another thread in C#?).

[Chỉnh sửa] Vừa xem bản cập nhật của bạn. Nếu đó là một ứng dụng giao diện điều khiển thì thao tác này sẽ hoạt động. Nhưng nếu bạn chưa sử dụng nhiều luồng cho đến nay, thì bạn cần phải biết rằng mã này sẽ được thực hiện trong một luồng khác, có nghĩa là bạn sẽ phải quan tâm đến các vấn đề đồng bộ hóa luồng.

Nếu bạn không cần nhân viên làm nền, hãy chú ý "giữ đơn giản".

2

Đây là một lớp tạm dừng sẽ tạm dừng cho các mili giây mong muốn và sẽ không tiêu tốn tài nguyên CPU của bạn.

class PauseClass 
{ 
    //(C) Michael Roberg 
    //Please feel free to distribute this class but include my credentials. 

    System.Timers.Timer pauseTimer = null; 

    public void BreakPause() 
    { 
     if (pauseTimer != null) 
     { 
      pauseTimer.Stop(); 
      pauseTimer.Enabled = false; 
     }  
    } 

    public bool Pause(int miliseconds) 
    { 
     ThreadPriority CurrentPriority = Thread.CurrentThread.Priority; 

     if (miliseconds > 0) 
     { 
      Thread.CurrentThread.Priority = ThreadPriority.Lowest; 

      pauseTimer = new System.Timers.Timer(); 
      pauseTimer.Elapsed += new ElapsedEventHandler(pauseTimer_Elapsed); 

      pauseTimer.Interval = miliseconds; 
      pauseTimer.Enabled = true; 

      while (pauseTimer.Enabled) 
      { 
       Thread.Sleep(10); 
       Application.DoEvents(); 
       //pausThread.Sleep(1); 
      } 

      pauseTimer.Elapsed -= new ElapsedEventHandler(pauseTimer_Elapsed); 
     } 

     Thread.CurrentThread.Priority = CurrentPriority; 

     return true; 
    } 

    private void pauseTimer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     pauseTimer.Enabled = false; 
    } 
} 
Các vấn đề liên quan