我正在使用C#4.0。我有一段代码,我想每2-3分钟执行一次。使用4.0线程功能可以做到这一点的正确方法是什么?
答案 0 :(得分:1)
使用System.Threading.Timer。
new Timer(TimerTick,null,TimeSpan.Zero,TimeSpan.FromMinutes(2));
private void TimerTick(object obj)
{
Thread myThread = new Thread(() => {});
myThread.Start();
}
答案 1 :(得分:1)
最简单的方法是使用System.Threading.Timer。要记住的一件事是它会忽略你的代码正在做什么(重入)。换句话说,如果所需的时间间隔为3分钟,并且您执行的代码需要2分钟,则在此代码完成后1分钟将触发。此外,如果您的代码需要超过3分钟,那么它将被并行调用,您将不得不处理线程安全。如果这没关系,并且您不希望您的代码需要很长时间,那么您可以使用以下内容:
Timer _timer = new Timer(DoWork, "someArg", TimeSpan.Zero, TimeSpan.FromSeconds(3));
private void DoWork(object state) {
// this code will get executed every 3 seconds:
String argument = (String) state;
}
但是如果你想让你的计时器顺序(等待代码在开始新的间隔之前完成),你需要在每个Tick上重置它。
Timer _timer = new Timer(DoWork, "someArg", TimeSpan.Zero, TimeSpan.FromSeconds(3));
private void DoWork(object state) {
// this code will get executed 3 seconds after the last DoWork finished
String argument = (String)state;
// make sure that timer will get executed in 3 seconds but will not repeat.
// this code guarantees that timer will wait for this code to complete
// before starting new interval.
_timer.Change(TimeSpan.FromSeconds(3), TimeSpan.FromMilliseconds(-1));
}
您还需要确保您的计时器实例在您仍然需要时不会收集垃圾。另请注意,.NET包含3个不同的计时器类,但您很可能需要 System.Threading.Timer 而不是 System.Windows.Forms.Timer 而不是系统。 Timers.Timer 即可。有完整的摘要here
如果您预见到更高级的计划要求(每隔一个星期一运行代码等),那么您可以使用Quartz.NET。它是一个开源的企业作业调度程序,具有许多其他功能,并且相对易于集成(参考一个dll)。
答案 2 :(得分:1)
我前段时间为无限线程处理编写了一个实用程序类。这就是....
public interface IProcessorThread
{
void Start();
void Stop();
}
public abstract class BaseProcessorThread : IProcessorThread
{
protected Boolean IsRunning;
protected readonly Thread ServiceThread;
protected readonly Int32 PollingFrequencySeconds;
#region Constructors
protected BaseProcessorThread(Int32 pollingFrequencySeconds)
{
this.PollingFrequencySeconds = pollingFrequencySeconds;
ServiceThread = new Thread(Process);
}
#endregion
#region Protected Methods
protected abstract void Process();
#endregion
#region Public Methods
public void Start()
{
IsRunning = true;
ServiceThread.Start();
}
public void Stop()
{
IsRunning = false;
ServiceThread.Join(2000);
}
#endregion
}
public class LifetimeInfiniteThread : BaseProcessorThread
{
#region Fields
private readonly Action actionMethod;
private readonly Action<Exception> exceptionMethod;
#endregion
#region Constructors
public LifetimeInfiniteThread(Int32 pollingFrequencySeconds, Action actionMethod, Action<Exception> exceptionMethod)
: base(pollingFrequencySeconds)
{
this.actionMethod = actionMethod;
this.exceptionMethod = exceptionMethod;
}
#endregion
#region Protected Methods
protected override void Process()
{
while (IsRunning)
{
try
{
actionMethod.Invoke();
}
catch (Exception ex)
{
exceptionMethod.Invoke(ex);
}
Thread.Sleep(PollingFrequencySeconds * 1000);
}
}
#endregion
}
<强>用法:强>
static void Main(string[] args)
{
// Using 60 for 1 minute.
var thread = new LifetimeInfiniteThread(60, Run, HandleException);
thread.Start();
Console.Read();
thread.Stop();
}
static void Run()
{
Console.WriteLine("I m running..");
}
static void HandleException(Exception ex)
{
Console.WriteLine(ex.Message);
}
答案 3 :(得分:1)
一种非常简单的方法是使用Reactive Extensions
var timer = Observable.Interval(TimeSpan.FromMinutes(2));
timer.Subscribe(tick => { //execute me });
正在执行的代码将由线程池工作线程处理,因此如果它访问共享状态,您需要确保具有正确的安全防护。
答案 4 :(得分:0)
您可以使用System.Threading.Timer
课程:
http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx
答案 5 :(得分:0)
使用计时器的解决方案:
public class Worker : IDisposable
{
private readonly System.Threading.Timer _timer;
private readonly int PeriodInMs = (int)TimeSpan.FromMinutes(2).TotalMilliseconds;
public Worker()
{
_timer = new System.Threading.Timer(_ => OnTick(), null, Timeout.Infinite, Timeout.Infinite);
}
public void Start()
{
_timer.Change(0, PeriodInMs);
}
public void Stop()
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
}
private void OnTick()
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
try
{
//Your work goes here
}
finally
{
_timer.Change(PeriodInMs, PeriodInMs);
}
}
public void Dispose()
{
_timer.Dispose();
}
}