Làm cách nào để lặp lại chuỗi với khoảng thời gian chính xác? C#

lập trình


C#
 private volatile bool _pause = false;
 private ManualResetEvent _pauseEvent = new ManualResetEvent(true);
 private Thread m_thread;
 private bool _istoday = true;
 private bool _isTimer_stop = false;
 private bool _thread_start = true;

private void btn_start_Click(object sender, EventArgs e)
 {

     int timer_interval = (int)numeric_app_freequency.Value;

         timer1_Tick(sender, e);
         timer1.Interval = 60 * 1000 * timer_interval;
         timer1.Enabled = true;
         timer1.Start(); //

 }

 private void timer1_Tick(object sender, EventArgs e)
 {
     if (_thread_start == true)
       {
         _thread_start = false;
         _istoday = true;
         m_thread = new Thread(new ThreadStart(begin_thread));
         m_thread.Name = "thred_1";
         m_thread.IsBackground = true;
         m_thread.Start();

        }

 }

 private void begin_thread()
 {

     int pageNum = 1;

     while (_pauseEvent.WaitOne())
     {
         if (_istoday == true)
         {

             parse_trs(pageNum);
             pageNum++;

         }
         else
         {
             Textbox1.Text = "Work is done"; ;
             break;
         }

     }
     _autoEvent.Set();
 }

 private void parse_trs(int pageNum)
 {
     string str_pageNum = pageNum.ToString();

     string list_url = "http://somedomain.com/bbs/board.php?bo_table=funny&page=" + str_pageNum;

     WebClient client = new WebClient();
     string sourceUrl = client.DownloadString(list_url);

     HtmlAgilityPack.HtmlDocument mydoc = new HtmlAgilityPack.HtmlDocument();

     mydoc.LoadHtml(sourceUrl);


     HtmlNodeCollection tr_col = mydoc.DocumentNode.SelectNodes("/ html / body//div[@id="bo_list"]//table/tbody/tr");

     foreach (HtmlNode node in tr_col)
     {

         _pauseEvent.WaitOne();


         if (post_date == today_date)
         {

             Do work.......................................

         }
         else
         {
             _istoday = false;
             break;
         }

     }
 }

Những gì tôi đã thử:

Tôi đã sử dụng vòng lặp while thay vì bộ đếm thời gian nhưng CPU quá tải nên ứng dụng bị treo

Giải pháp 1

Đây có lẽ là thiết kế tồi tệ nhất có thể để nhận được một số hành vi định kỳ gần như định kỳ của một luồng. Có nhiều lý do cho việc đó, không cần phải bàn hết. Chi phí tạo một phiên bản luồng mới và khởi động nó là một trong những yếu tố, nhưng cho đến nay, đó không phải là yếu tố tồi tệ nhất. Điều tồi tệ nhất là khả năng dễ dàng làm rối tung mọi thứ.

Giải pháp đơn giản tốt hơn nhiều sẽ là chỉ tạo một luồng bổ sung và giữ cho nó hoạt động trong suốt thời gian tồn tại của ứng dụng. Bạn chỉ cần làm cho nó thực thi trong một vòng lặp “vô hạn” (trên thực tế, chỉ bị hỏng khi ứng dụng sắp đóng) và điều tiết hoạt động của nó bằng cách sử dụng một đối tượng xử lý chờ sự kiện.

Điều quan trọng là phải hiểu rằng trong cuộc gọi WaitHandle.WaitOne luồng hoặc được chuyển hoặc được đặt ở một vị trí đặc biệt trạng thái chờ; nó bị tắt và không bao giờ được lên lịch thực hiện lại cho đến khi nó được đánh thức, điều này xảy ra vào Thread.Abort, Thread.Interrupt, thời gian chờ và các sự kiện khác, đặc biệt là báo hiệu đối tượng xử lý chờ từ một luồng khác. Bằng cách này, luồng không sử dụng thời gian CPU ở trạng thái chờ, không có thời gian chờ quay, không kiểm tra trạng thái định kỳ, không có gì.

Xin vui lòng xem: Lớp EventWaitHandle (System.Threading)[^].

Xin vui lòng xem câu trả lời trước đây của tôi:
Làm cho luồng mã an toàn[^],
tạm dừng chủ đề đang chạy[^],
ManualResetEvent và AutoResetEvent trong Chủ đề[^],
Chạy chính xác một công việc/luồng/quy trình trong dịch vụ web sẽ không bao giờ bị chấm dứt (asp.net)[^].

Đặc biệt chú ý đến kỹ thuật liên quan thay thế bằng cách sử dụng bộ sưu tập chặn; nó không liên quan đến câu hỏi trước mắt của bạn nhưng điều quan trọng là phải hiểu.

Bây giờ chúng ta hãy quay trở lại với việc lặp lại “định kỳ” theo bộ đếm thời gian. Tôi không chắc bạn cần nó theo cách này. Một giải pháp thay thế là chỉ lặp lại đoạn mã trong một luồng, lấy thời gian thực hiện tại từ, ví dụ: System.DateTime.Nowtính toán thời gian thực hiện tiếp theo và gọi Thread.Sleep với thời lượng thích hợp. Nhưng nếu bạn thực sự cần một bộ đếm thời gian (một lần nữa, tôi không biết tại sao), chức năng duy nhất của nó sẽ là báo hiệu sự kiện chờ xử lý bằng cách gọi EventWaitHandle.Set(), đánh thức luồng đang chờ trên phiên bản xử lý sự kiện này. Lưu ý rằng cuộc gọi này an toàn theo luồng, không giống như hầu hết mọi cuộc gọi khác của một số phương thức. Cũng lưu ý rằng sự kiện hẹn giờ xảy ra trong một số chủ đề mà bạn không biết (ngoại trừ việc thực sự xấu System.Windows.Forms.Timer gọi trình xử lý đánh dấu trong chuỗi giao diện người dùng, nhưng “sự nhẹ nhõm” này chỉ mang lại lợi ích duy nhất; trong hầu hết các trường hợp, nó không bao giờ nên được sử dụng vì thời gian rất tệ).

Cả hai kỹ thuật đều giải quyết được vấn đề lớn nhất mà bạn có thể gặp phải. Điều gì có thể xảy ra nếu bạn bắt đầu một số quá trình xử lý nếu quá trình xử lý do dấu tích bộ đếm thời gian trước đó của bạn gây ra vẫn chưa hoàn tất? Thật khó để tưởng tượng tất cả những rắc rối có thể xảy ra. Các giải pháp tôi đề xuất hoàn toàn không gặp phải vấn đề này.

-SA

コメント

タイトルとURLをコピーしました