c#多个任务运行在后台独立不互相阻塞
c# multiple tasks running in background independently without blocking each other
我有一个 C# Windows 服务,运行里面有一些任务。
其中一个任务是无限异步循环,其他任务由定时器触发,然后执行任务。
private readonly QueueProcessor _queueProcessor;
protected override void OnStart(string[] args)
{
// first task
_queueTask = _queueProcessor.Run(_cancellation.Token);
// second task
affiliate_timer = new System.Timers.Timer();
affiliate_timer.AutoReset = true;
affiliate_timer.Interval = _model.Interval_Affiliate * 60000;
affiliate_timer.Elapsed += new
System.Timers.ElapsedEventHandler(affiliate_timer_Elapsed);
// third task
invoice_timer = new System.Timers.Timer();
invoice_timer.AutoReset = true;
invoice_timer.Interval = _model.Interval_Invoice * 60000;
invoice_timer.Elapsed += new
System.Timers.ElapsedEventHandler(invoice_timer_Elapsed);
}
private void invoice_timer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
{
if (!_isAffiliateBusy)
{
_isAffiliateBusy= true;
var task = Task.Run(() => StartAffiliateTask());
task.Wait();
_isAffiliateBusy= false;
}
}
private void invoice_timer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
{
if (!_isInvoiceBusy)
{
_isInvoiceBusy = true;
var task = Task.Run(() => StartInvoiceTask());
task.Wait();
_isInvoiceBusy = false;
}
}
private void StartAffiliateTask()
{
_affiliateModule = new Modules.Affiliate();
_affiliateModule.RunSync();
}
private void StartInvoiceTask()
{
_invoiceModule = new Modules.Invoice();
_invoiceModule.RunSync();
}
这是我的 QueueProcessor
class 实现 await/async
以执行无限循环作业:
public class QueueProcessor
{
private readonly IQueueBroker _serviceBroker;
public QueueProcessor()
{
}
public async Task Run(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
var receiveMessageResponse = await _serviceBroker.ReceiveMessageAsync("test", cancellationToken);
if (!receiveMessageResponse.Messages.Any())
{
continue;
}
foreach (var message in receiveMessageResponse.Messages)
{
// some other tasks here...
await _serviceBroker.DeleteMessageAsync(message, cancellationToken);
}
}
}
}
我的 Affiliate
和 Invoice
模块 classes 没有 实现任何 await/async
内部代码如下所示:
public class Affiliate
{
/// <summary>
/// Start the sync process
/// </summary>
public void RunSync()
{
try
{
// some code here...
}
catch (Exception ex)
{
}
}
}
我的问题是:
当我的队列处理器无限循环 运行ning 时,我的其他由计时器触发的任务是否仍然可以独立 运行?
当我使用:
var task = Task.Run(() => StartAffiliateTask());
task.Wait();
Wait 方法是否会停止整个服务线程,直到此任务完成?或者这不会独立地阻止我的 StartInvoiceTask
到 运行?
Any recommendation on the best way to have my 3 tasks running independant on each other?
总结多个潜在问题:
- 竞争条件(access/write 到 _isBusy)。
- 潜在的死锁(线程池大小较低)。
- 在错误或线程中止的情况下标志的潜在不一致状态(_isBusy 可以留在 'true' 状态)。
此外,我假设您的 'task' 在单个实例中应该是 运行,因此如果它仍然是 运行,我们将忽略计时器回调。
您应该像这样更改计时器事件处理程序(最好将其包装在某种 class 中):
//the flag, do mention volatile modifier - it tells particular
//systems to watch for variable changes by reference,
//instead of just copying it into thread stack by value.
private volatile bool _isAffiliateBusy = false;
//sync object for flag to eliminate race condition
private object _affiliateSync = new object();
private void affiliate_timer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
{
//very fast lookup at flag to filter threads which comes when task is still processing
if(_isAffiliateBusy)
return;
lock(_affiliateSync) //taking lock
{
//checking again for those threads which 'happen' to be faster than you think.
if(_isAffiliateBusy)
return;
//aquire lock for business 'task'
_isAffiliateBusy = true;
}
try
{
StartAffiliateTask();
}
finally
{
//resetting singleton business 'task' lock.
//do not forget to use finally block, to handle disposing
//even if something rise up in 'try' section - you will not be left with invalid state of flag.
_isAffiliateBusy = false;
}
}
我有一个 C# Windows 服务,运行里面有一些任务。
其中一个任务是无限异步循环,其他任务由定时器触发,然后执行任务。
private readonly QueueProcessor _queueProcessor;
protected override void OnStart(string[] args)
{
// first task
_queueTask = _queueProcessor.Run(_cancellation.Token);
// second task
affiliate_timer = new System.Timers.Timer();
affiliate_timer.AutoReset = true;
affiliate_timer.Interval = _model.Interval_Affiliate * 60000;
affiliate_timer.Elapsed += new
System.Timers.ElapsedEventHandler(affiliate_timer_Elapsed);
// third task
invoice_timer = new System.Timers.Timer();
invoice_timer.AutoReset = true;
invoice_timer.Interval = _model.Interval_Invoice * 60000;
invoice_timer.Elapsed += new
System.Timers.ElapsedEventHandler(invoice_timer_Elapsed);
}
private void invoice_timer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
{
if (!_isAffiliateBusy)
{
_isAffiliateBusy= true;
var task = Task.Run(() => StartAffiliateTask());
task.Wait();
_isAffiliateBusy= false;
}
}
private void invoice_timer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
{
if (!_isInvoiceBusy)
{
_isInvoiceBusy = true;
var task = Task.Run(() => StartInvoiceTask());
task.Wait();
_isInvoiceBusy = false;
}
}
private void StartAffiliateTask()
{
_affiliateModule = new Modules.Affiliate();
_affiliateModule.RunSync();
}
private void StartInvoiceTask()
{
_invoiceModule = new Modules.Invoice();
_invoiceModule.RunSync();
}
这是我的 QueueProcessor
class 实现 await/async
以执行无限循环作业:
public class QueueProcessor
{
private readonly IQueueBroker _serviceBroker;
public QueueProcessor()
{
}
public async Task Run(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
var receiveMessageResponse = await _serviceBroker.ReceiveMessageAsync("test", cancellationToken);
if (!receiveMessageResponse.Messages.Any())
{
continue;
}
foreach (var message in receiveMessageResponse.Messages)
{
// some other tasks here...
await _serviceBroker.DeleteMessageAsync(message, cancellationToken);
}
}
}
}
我的 Affiliate
和 Invoice
模块 classes 没有 实现任何 await/async
内部代码如下所示:
public class Affiliate
{
/// <summary>
/// Start the sync process
/// </summary>
public void RunSync()
{
try
{
// some code here...
}
catch (Exception ex)
{
}
}
}
我的问题是:
当我的队列处理器无限循环 运行ning 时,我的其他由计时器触发的任务是否仍然可以独立 运行?
当我使用:
var task = Task.Run(() => StartAffiliateTask());
task.Wait();
Wait 方法是否会停止整个服务线程,直到此任务完成?或者这不会独立地阻止我的 StartInvoiceTask
到 运行?
Any recommendation on the best way to have my 3 tasks running independant on each other?
总结多个潜在问题:
- 竞争条件(access/write 到 _isBusy)。
- 潜在的死锁(线程池大小较低)。
- 在错误或线程中止的情况下标志的潜在不一致状态(_isBusy 可以留在 'true' 状态)。
此外,我假设您的 'task' 在单个实例中应该是 运行,因此如果它仍然是 运行,我们将忽略计时器回调。 您应该像这样更改计时器事件处理程序(最好将其包装在某种 class 中):
//the flag, do mention volatile modifier - it tells particular
//systems to watch for variable changes by reference,
//instead of just copying it into thread stack by value.
private volatile bool _isAffiliateBusy = false;
//sync object for flag to eliminate race condition
private object _affiliateSync = new object();
private void affiliate_timer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
{
//very fast lookup at flag to filter threads which comes when task is still processing
if(_isAffiliateBusy)
return;
lock(_affiliateSync) //taking lock
{
//checking again for those threads which 'happen' to be faster than you think.
if(_isAffiliateBusy)
return;
//aquire lock for business 'task'
_isAffiliateBusy = true;
}
try
{
StartAffiliateTask();
}
finally
{
//resetting singleton business 'task' lock.
//do not forget to use finally block, to handle disposing
//even if something rise up in 'try' section - you will not be left with invalid state of flag.
_isAffiliateBusy = false;
}
}