gpt4 book ai didi

C# 每 X 分钟运行一个线程,但前提是该线程尚未运行

转载 作者:IT王子 更新时间:2023-10-29 03:44:49 26 4
gpt4 key购买 nike

我有一个 C# 程序需要每 X 分钟分派(dispatch)一个线程,但前提是先前分派(dispatch)的线程(从 X 分钟前开始)当前没有运行

单独使用一个普通的旧式 Timer 是行不通的(因为它每 X 分钟调度一次事件,而不管之前调度的进程是否已经完成)。

要分派(dispatch)的进程执行任务所需的时间差异很大 - 有时可能需要一秒钟,有时可能需要几个小时。如果它从上次启动时仍在处理,我不想再次启动该过程。

谁能提供一些有效的 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 类还支持进度报告和取消,并使用事件驱动模型与调度线程进行通信,因此您不必担心 volatile 变量等...

编辑

下面是更详细的示例,包括取消和进度报告:

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()。请注意,这是完全由用户处理的取消机制(它不支持线程中止或任何类似开箱即用的机制)。

关于C# 每 X 分钟运行一个线程,但前提是该线程尚未运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12570324/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com