所以我有一个计时器,每秒运行一次。大多数情况下,运行只需几毫秒,但有时执行一个计时器,超过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,它将在每次运行时被覆盖。
任何想法?
答案 0 :(得分:1)
由于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;
}
}
在计时器回调中将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);
答案 1 :(得分:1)
您是否需要方法本身来了解上下文?或者您只需要知道事件处理程序吗?
实现此目的的最简单方法是使用事件处理程序在同一个类中维护一个计数器:
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,您将这些方法的代码放入其中,以及当前计数器的值:
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
类的成员)都可以访问该计数器。
这些只是您可以采取的几种不同方法。当然,还有其他选择,但希望上面的内容能让您了解这些选项的工作原理(它们都是主题的变体)。