簡體   English   中英

如何在C#中使用信號機制與線程和manualresetevent進行密集工作(不重疊)?

[英]How to use signalling mechanism for performing intensive work (that do not overlap) with a thread and manualresetevent in C#?

我有一個現有應用程序,每個numOfMinutesInterval都有1個線程在后台運行一些繁重的工作。 以前使用Thread.Sleep (在整個時間間隔內休眠)來完成此操作,但是我已經讀過Thread.Sleep是邪惡的,它的設計很草率,所以我想更改一種信號機制。 下面是我剛編寫的代碼(使用wpf的調度程序計時器,但是我認為在這種小情況下,winforms計時器也是如此)。

調度程序(在UI線程中運行)每秒鍾滴答一次,並且在tick函數內部,它檢查間隔是否已經過去,如果已經過去,則將向manualresetevent Set()發出信號。 我想知道如果密集的工作超出了間隔時間,這是否是一個不好的設計? 如果我將numOfMinutesInterval = 1設置為numOfMinutesInterval = 1 ,但是工作耗時1分1秒,那是否意味着我們將跳過1 set()調用,因為滴答是在工作仍在進行時嘗試set()事件,並且工作線程尚未阻塞。

另請注意,我已經設置了lastWorkDoneTime = DateTime.Now; 在調用Set() ,我是否應該將其移至工作線程(調用lastWorkDoneTime = DateTime.Now;就在manualResetEvent.WaitOne();之前)?

如果這是不好的設計,我應該怎么做才能改變它? 謝謝閱讀!

//thread work done here
private void MyDoWork_ThreadStart() 
{
  while(FlagApplicationStillRunning == true)
  {
    //do the intensive work here
    manualResetEvent.WaitOne();
  }
}


// tick every second
private int numOfMinutesInterval = 1;
private DateTime lastWorkDoneTime = DateTime.Now;
private void DispatcherTimer_Tick(object sender, EventArgs e) 
{
  if((DateTime.Now - lastWorkDoneTime).Minutes > numOfMinutesInterval)
  {
    manualResetEvent.Set();
    lastWorkDoneTime = DateTime.Now;
  }
}

您可以開始一項任務,然后執行繁重的工作。

private void DispatcherTimer_Tick(object sender, EventArgs e) 
{
    if ((DateTime.Now - lastWorkDoneTime).Minutes > numOfMinutesInterval)
    {
        Task.Factory.StartNew(DoIntensiveWork());
        lastWorkDoneTime = DateTime.Now;
    }
}

至於設置由您決定的lastWorkDoneTime 如果將其設置為激發任務的對象,則有可能同時運行兩個或多個任務以執行工作。 如果將其設置在執行工作的功能的末尾,則會導致延遲,延遲取決於完成工作所需的時間。

我實際上會考慮使用計時器對象之一,並讓它為您處理計時,而不是使用DispatcherTimer_Tick事件。 System.Timers.TimerSystem.Threading.Timers等。

為了幫助確定哪種計時器選項最適合您: 比較.NET Framework類庫中的計時器類

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM