Bagaimana cara mengulang thread dengan interval yang tepat? C#

pemrograman


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;
         }

     }
 }

Apa yang saya coba:

Saya telah menggunakan while loop alih-alih pengatur waktu tetapi cpu kelebihan beban sehingga aplikasi terhenti

Solusi 1

Ini mungkin desain terburuk untuk mendapatkan perilaku thread yang periodik dan hampir periodik. Ada banyak alasan untuk itu, tidak perlu membahas semuanya. Biaya pembuatan instance thread baru dan memulainya adalah salah satu faktornya, namun sejauh ini bukan yang terburuk. Hal terburuknya adalah kemungkinan mudah untuk mengacaukan segalanya.

Solusi langsung yang jauh lebih baik adalah dengan membuat hanya satu thread tambahan dan menjaganya tetap berjalan selama hampir seluruh masa pakai aplikasi. Anda cukup membuatnya dieksekusi dalam loop “tak terbatas” (pada kenyataannya, hanya terputus saat aplikasi akan ditutup) dan membatasi aktivitasnya dengan menggunakan objek event wait handle.

Penting untuk memahami hal itu saat menelepon WaitHandle.WaitOne utasnya lolos atau dimasukkan ke khusus keadaan tunggu; itu dimatikan dan tidak pernah dijadwalkan kembali ke eksekusi sampai dibangunkan, yang terjadi pada Thread.Abort, Thread.Interrupt, batas waktu, dan kejadian lainnya, khususnya, menandakan objek pegangan tunggu dari thread lain. Dengan cara ini, thread tidak menghabiskan waktu CPU dalam status menunggu, tidak ada putaran tunggu, tidak ada pemeriksaan status secara berkala, tidak ada apa pun.

Silahkan lihat: Kelas EventWaitHandle (Sistem.Threading)[^].

Silakan lihat jawaban saya sebelumnya:
Membuat Thread Kode Aman[^],
jeda thread yang sedang berjalan[^],
ManualResetEvent dan AutoResetEvent di Thread[^],
Menjalankan tepat satu pekerjaan/utas/proses di layanan web yang tidak akan pernah dihentikan (asp.net)[^].

Berikan perhatian khusus pada teknik alternatif terkait penggunaan koleksi pemblokiran; ini tidak ada hubungannya dengan pertanyaan langsung Anda tetapi penting untuk dipahami.

Sekarang, mari kita kembali ke pengulangan “berkala” berdasarkan pengatur waktu. Saya tidak yakin Anda membutuhkannya dengan cara ini. Salah satu alternatifnya adalah dengan mengulangi potongan kode di threadnya sendiri, mengambil waktu nyata saat ini dari, katakanlah, System.DateTime.Nowperhitungan waktu eksekusi berikutnya dan panggilan Thread.Sleep dengan durasi yang sesuai. Tetapi jika Anda benar-benar membutuhkan pengatur waktu (sekali lagi, saya tidak tahu mengapa), satu-satunya fungsinya adalah memberi sinyal event wait handle dengan menelepon EventWaitHandle.Set(), yang membangunkan thread yang menunggu pada instance event handle ini. Perhatikan bahwa panggilan ini aman untuk thread, tidak seperti hampir semua panggilan metode lainnya. Perhatikan juga bahwa peristiwa pengatur waktu terjadi di beberapa utas yang tidak Anda ketahui (kecuali sangat buruk System.Windows.Forms.Timer yang memanggil penangan centang di thread UI, tapi “kelegaan” ini adalah satu-satunya keuntungannya; dalam kebanyakan kasus, ini tidak boleh digunakan, karena waktunya sangat buruk).

Kedua teknik ini memecahkan masalah terbesar yang mungkin Anda hadapi. Apa yang bisa terjadi jika Anda memulai beberapa pemrosesan jika pemrosesan yang disebabkan oleh centang pengatur waktu sebelumnya belum selesai? Sulit membayangkan semua kekacauan yang mungkin terjadi. Solusi yang saya sarankan sepenuhnya bebas dari masalah ini.

-SA

コメント

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