[英]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.Timer
, System.Threading.Timers
等。
為了幫助確定哪種計時器選項最適合您: 比較.NET Framework類庫中的計時器類
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.