![](/img/trans.png)
[英]Different behaviour of System.Timers.Timer and System.Threading.Timer
[英]Identify different timer runs (System.Timers.Timer)
所以我有一個計時器,每秒運行一次。 大多數情況下,運行只需幾毫秒,但有時執行一個計時器,超過1秒。 這本身不是問題,因為c#處理將不同的運行放在不同(或相同)的線程等。
但是,如果我想通過哪個運行調用某個方法,同時執行2次運行,該怎么辦? 我想在我的控制台中有一個輸出,如:
Run 1: Method "GetThisStuff" called
Run 1: Method "GetOtherStuff" called
Run 2: Method "GetThisStuff" called
Run 1: Method "GetFinalStuff" called
Run 2: Method "GetOtherStuff" called
Run 2: Method "GetFinalStuff" called
如果我有一個計時器方法
public static void timer_Elapsed(object sender, ElapsedEventArgs e) {
GetMainStuff();
GetMoreMainStuff();
}
還有一些虛擬方法:
public void GetMainStuff()
{
GetThisStuff();
GetOtherStuff();
}
public void GetMoreMainStuff()
{
GetFinalStuff();
}
我知道有
ElapsedEventArgs.SignalTime
但我不想通過我的應用程序的每個方法(以下幾個“級別”)將此作為參數。
我也知道,並非每一個新的運行都會有一個新線程。
如果我有一個靜態記憶的SignalTime,它將被覆蓋每次運行。
有任何想法嗎?
由於System.Timers.Timer
未密封,您可以擴展它以添加Counter屬性:
public class TimerWithRunCounter : System.Timers.Timer
{
public int Counter { get; set; }
public TimerWithRunCounter(int counter, double interval) : base(interval)
{
Counter = counter;
}
}
在定時器回調TimerWithRunCounter
sender
為TimerWithRunCounter
並訪問並遞增計數器:
public static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
var timer = (TimerWithRunCounter)sender;
lock (lockObject)
{
Console.WriteLine("Run {0}", timer.Counter);
timer.Counter++;
}
}
用法示例:
var timer = new TimerWithRunCounter(0, 1000);
你需要方法本身來了解背景嗎? 或者您只需要知道事件處理程序?
完成此操作的最簡單方法是使用事件處理程序在同一個類中維護一個計數器:
private static int _timerCounter;
public static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
int counter = Interlocked.Increment(ref _timerCounter);
GetMainStuff();
GetMoreMainStuff();
}
如果每個被調用的方法都需要知道這個值,那么你當然可以傳遞這個值:
public static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
int counter = Interlocked.Increment(ref _timerCounter);
GetMainStuff(counter);
GetMoreMainStuff(counter);
}
如果你有一個深度調用鏈,你想在整個上下文中廣泛地知道計數器,那么你可以繼續上面的模式,將值傳遞給每個被調用的方法,或者你可以創建一個“調用上下文”類,您將這些方法的代碼以及當前計數器的值放入其中:
class TimerContext
{
private readonly int _timerCount;
public int TimerCount { get { return _timerCount; } }
public TimerContext(int timerCount)
{
_timerCount = timerCount;
}
public void GetMainStuff()
{
GetThisStuff();
GetOtherStuff();
}
public void GetMoreMainStuff()
{
GetFinalStuff();
}
// etc.
}
public static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
TimerContext context = new TimerContext(Interlocked.Increment(ref _timerCounter));
context.GetMainStuff();
context.GetMoreMainStuff();
}
這樣,您調用的每個方法(作為TimerContext
類的成員)都可以訪問計數器。
這些只是您可以采取的幾種不同方法。 當然,還有其他選擇,但希望上面的內容能讓您了解這些選項的工作原理(它們都是主題的變體)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.