我有一個由工作項集合組成的作業對象。每個作業都有自己的與之相關的WatcherClass
,它經常檢查數據庫以查看是否需要取消執行。它可以在工作流程的任何迭代中被取消。如果它被取消,則從foreach
塊運行的任何線程都會傳播取消並正常退出。使用相同的鎖修改鎖內的對象
我的監視器代碼中是否有任何問題可能導致死鎖?我試圖只允許一個線程處理定時器回調通過使用Timer.Change(Timeout.Infinite,Timeout.Infinite),但事實上,我改變WatcherClass.Job
裏面的鎖定聲明擊敗鎖的目的(因爲我包裹同一個鎖對象中的_Job的get/set)?該代碼似乎工作正常,但我知道這並不是什麼跡象。
在主線程的代碼看起來類同此:
using (WatcherClass watcher = new WatcherClass())
{
watcher.CancelTokenSource = new CancellationTokenSource();
watcher.Start();
foreach (SomeJob job in worksflow.Jobs)
{
watcher.Job = job;
//Do some stuff async
//Do some more stuff async
}
}
public class WatcherClass : IDisposable
{
private System.Threading.Timer _WatcherTimer;
private readonly object locker = new object();
private bool _Disposed = false;
private SomeJob _Job;
public SomeJob Job
{
get
{
lock (locker)
{
return _Job;
}
}
set
{
lock (locker)
{
_Job= value;
}
}
}
public System.Threading.Task.CancellationTokenSource
CancelToken { get; set; }
public WatcherClass()
{
_WatcherTimer = new Timer(new TimerCallback(DoCheck), null,
Timeout.Infinite, Timeout.Infinite);
}
public void Start()
{
_WatcherTimer.Change(30000, Timeout.Infinite);
}
public void DoCheck(object state)
{
lock (locker)
{
if (_Disposed || this.CancelToken.IsCancellationRequested)
return;
_WatcherTimer.Change(Timeout.Infinite, Timeout.Infinite);
//Check database to see if task is cancelled
if (cancelled)
{
this.CancelToken.Cancel();
_Job.CancelResult = CancelResult.CanceledByUser;
_Job.SomeOtherProperty = true;
}
else
{
//Safe to continue
_WatcherTimer.Change(30000, Timeout.Infinite);
}
}
}
public void Dispose(bool disposing)
{
lock (locker)
{
if (disposing)
{
if (_WatcherTimer != null)
_WatcherTimer.Dispose();
}
_Disposed = true;
}
}
}
要清楚,這些是你的`類任務`,`類CancelToken`,而不是來自TPL的? – 2011-01-14 19:31:01
@亨克:CancelToken來自TPL,任務不是 - 任務就是我爲這個例子所調用的。謝謝 – 2011-01-14 19:35:56