작업 개체 모음으로 구성된 작업 개체가 있습니다. 각 작업에는 데이터베이스가 자주 체크되어 실행을 취소해야하는지 확인하는 고유 한 WatcherClass
이 있습니다. 워크 플로우의 반복에 따라 취소 될 수 있습니다. 취소 된 경우 foreach
블록에서 실행중인 모든 스레드는 취소를 정상적으로 종료하고 종료합니다.동일한 잠금 장치로 잠금 장치 내부의 개체 수정
교착 상태가 발생할 수있는 워처 코드에 문제가 있습니까? Timer.Change (Timeout.Infinite, Timeout.Infinite)를 사용하여 타이머 콜백을 처리하는 스레드를 하나만 허용하려고합니다.하지만 실제로 변경됩니다. WatcherClass.Job
잠금 문이 잠금 문장을 감싸기 때문에 래핑 된 이후로 동일한 잠금 개체에서 _Job에 대해 동일한 가져 오기/설정)? 코드가 정상적으로 작동하는 것으로 보입니다.하지만 실제로는 아무 것도 알 수 없습니다.
메인 스레드에서 코드는 다음에 비슷한 같습니다
는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;
}
}
}
분명히하기 위해, 이것들은'class task','class CancelToken'이며 TPL의 것들이 아닙니다. –
@Henk : CancelToken은 TPL에서 가져온 것입니다. 작업은 아닙니다.이 예제에서는 작업을 호출했습니다. 감사합니다 –
어쩌면 혼동을 피하기 위해 Job으로 바꿀 수도 있습니다. 특히 CancelToken을 사용할 경우 –