我有一个 C# 程序,需要每 X 分钟调度一个线程,但前提是之前调度的线程(从 X 分钟开始)当前尚未运行.
一个普通的老Timer
单独运行是行不通的(因为它每 X 分钟调度一个事件,无论先前调度的进程是否已完成)。
将要分派的进程执行其任务所需的时间差异很大 - 有时可能需要一秒钟,有时可能需要几个小时。如果该进程仍在上次启动时处理,我不想再次启动该进程。
谁能提供一些有效的 C# 示例代码?
在我看来,在这种情况下要走的路是使用System.ComponentModel.BackgroundWorker
类,然后简单地检查它的IsBusy
每次您想要分派(或不分派)新线程时。代码非常简单;这是一个例子:
class MyClass
{
private BackgroundWorker worker;
public MyClass()
{
worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
Timer timer = new Timer(1000);
timer.Elapsed += timer_Elapsed;
timer.Start();
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if(!worker.IsBusy)
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
//whatever You want the background thread to do...
}
}
在这个例子中我使用了System.Timers.Timer
,但我相信它也应该与其他计时器一起使用。这BackgroundWorker
该类还支持进度报告和取消,并使用事件驱动模型与调度线程进行通信,因此您不必担心易失性变量等...
EDIT
这是更详细的示例,包括取消和进度报告:
class MyClass
{
private BackgroundWorker worker;
public MyClass()
{
worker = new BackgroundWorker()
{
WorkerSupportsCancellation = true,
WorkerReportsProgress = true
};
worker.DoWork += worker_DoWork;
worker.ProgressChanged += worker_ProgressChanged;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
Timer timer = new Timer(1000);
timer.Elapsed += timer_Elapsed;
timer.Start();
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if(!worker.IsBusy)
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker w = (BackgroundWorker)sender;
while(/*condition*/)
{
//check if cancellation was requested
if(w.CancellationPending)
{
//take any necessary action upon cancelling (rollback, etc.)
//notify the RunWorkerCompleted event handler
//that the operation was cancelled
e.Cancel = true;
return;
}
//report progress; this method has an overload which can also take
//custom object (usually representing state) as an argument
w.ReportProgress(/*percentage*/);
//do whatever You want the background thread to do...
}
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//display the progress using e.ProgressPercentage and/or e.UserState
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Cancelled)
{
//do something
}
else
{
//do something else
}
}
}
然后,为了取消进一步执行,只需调用worker.CancelAsync()
。请注意,这是完全由用户处理的取消机制(它不支持线程中止或类似的开箱即用的机制)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)