我想实现某种方法来防止方法被立即多次调用。例如,假如我有一个类:
@reboot python /home/pi/x.py &
用户可以呼叫class Example
{
public void MyFunction()
{
// do something
}
}
,但仅限于自上次呼叫以来经过3秒。如果在3秒之前调用它,则不会发生任何事情(应忽略调用)。
我该怎么做?
编辑:
我不想使用MyFunction
。我在考虑使用Thread.Sleep
中的Timer类。但是我不知道如何根据自己的需要使用它。
答案 0 :(得分:9)
我不认为有必要在这里使用计时器。您可以使用Stopwatch
:
class Example
{
private static readonly TimeSpan MinInterval = TimeSpan.FromSeconds(3);
private readonly Stopwatch stopwatch = new Stopwatch(); // Stopped initially
public void MyFunction()
{
if (stopwatch.IsRunning && stopwatch.Elapsed < MinInterval)
{
return;
}
try
{
// Do stuff here.
}
finally
{
stopwatch.Restart();
}
}
}
请注意,此不是线程安全的...多个线程可以在同一个实例上同时执行该方法。每个实例都使用单独的秒表,因此多个线程可能会使用多个实例 - 如果要禁止跨所有实例的调用,则需要使用静态字段秒表,并且肯定会添加锁定以便安全地访问它。
另请注意,虽然您可以使用DateTime
来检测上次执行时间,但通过用户更改系统时钟很容易出错。
这里使用try
/ finally
是为了避免因快速连续的多次调用而导致异常被抛出。同样,这可能不是你想要的......你应该考虑是否做希望在呼叫失败时重置秒表。
答案 1 :(得分:3)
您可以声明班级的私人DateTime
字段,存储您的方法的最后通话时间,并检查与当前时间的差异:
class Example
{
private DateTime _MyFunctionLastCallTime = DateTime.MinValue;
private object _Lock = new object();
public void MyFunction()
{
lock(_Lock)
{
var now = DateTime.UtcNow;
if ((now - _MyFunctionLastCallTime).TotalSeconds < 3)
return;
_MyFunctionLastCallTime = now;
// the rest of code
}
}
}
答案 2 :(得分:3)
使用Diagnostics.Stopwatch
执行此操作:
class Program
{
static Stopwatch stopwatch = new Stopwatch();
static void Main(string[] args)
{
stopwatch.Start();
Todo();
Thread.Sleep(4000);
Todo();
}
public static void Todo()
{
if(stopwatch.Elapsed.TotalSeconds > 3)
{
// do stuff
stopwatch.Restart();
}
}
}
答案 3 :(得分:-2)
你不需要&#34;阻止&#34;任何事情也没有做任何与线程相关的事情,只是存储上次执行的时间并退出(或者抛出异常或做任何你想做的事情)如果它被调用的时间太短
private DateTime LastCalled;
public void MyFunc()
{
if (LastCalled > DateTime.Now.AddSeconds(-3)
{
return; // or do whatever else you want, throw an exception etc
};
LastCalled = DateTime.Now;
// Your actual method code here
}