제 질문은 어떻게 장기 실행 작업 (.net 4)을 중지 할 수 있습니까? TPL을 구현하고 CancellationTokenSource를 사용해 보았지만 제 시나리오에서는 작동하지 않습니다. 필자가 보았던 모든 예제는 while 루프에서 작업을 수행 중이므로 작업이 취소되었는지 확인할 수 있도록하는 반면, 필자는 오래 걸리는 단일 작업 만 수행한다고 가정합니다. 나는 그것이 완료되지 않을 것이라고 가정 할 필요가 있기 때문에 작업이 완료 될 때까지 기다릴 수 없습니다.장기 실행 작업을 안전하게 중단하십시오.
bool? result = null;
var cs = new CancellationTokenSource();
var ct = cs.Token;
var doWorkTask = new Task(() =>
{
Console.WriteLine("start dowork task");
result = Work.LongRunning();
}, ct);
doWorkTask.Start();
Task.WaitAny(new Task[] { doWorkTask }, timetowait);
if (doWorkTask.IsCompleted)
{
Console.WriteLine("dowork task completed");
doWorkTask.Dispose();
}
else
{
Console.WriteLine("dowork task has timedout");
cs.Cancel();
throw new TimeoutException("Timeout hit.");
}
코드는 작동하지만 "타임 아웃"이 발생하고 수행되고있는 작업 즉 자원 "관리되지 않는 코드"를 액세스하는 경우 작업이 배치되지 않습니다 : 는 여기에 내가 시도 코드입니다. IsCancelledRequested는 Work.LongRunning()에서 사용할 수 없으므로 ThrowIfCancellationRequested를 사용할 수 없습니다.
나는 BackgroundWorker를 시도했지만 다른 아이디어에 대해서도 개방적이지만 그 또한 적합하지 않은 것 같습니다.
새로운 예 :
var service = new System.ServiceProcess.ServiceController(ServiceName, ServerName);
var serviceTask = Task.Factory.StartNew(() =>
{
result = (service.Status == ServiceControllerStatus.Running
|| service.Status == ServiceControllerStatus.StartPending);
}, cs.Token);
serviceTask.Wait(2000, cs.Token);
if (!serviceTask.IsCompleted)
{
cs.Cancel();
}
감사합니다! Begin \ End 패턴을 살펴 봤지만 End의 결과를 확인하려면 (() isyncResult) 작업이 완료 될 때까지 기다려야합니다. 나는 나의 예를 들어 업데이트했다. 값을 확인하자마자 ServiceController의 프로퍼티가 게으른로드 된 것처럼 보입니다. –
nickv
코드를 완벽하게 따라갈 수는 없지만 ContinueWith를 사용하여 연속을 추가하지 않는 이유는 무엇입니까? ? – Stilgar
새로운 일을 계속하고 싶지 않기 때문에. 내가 수행하고자하는 하나의 작업이 있는데, 그 작업은 어떤 이유로 인해 응답을받지 못할 수 있습니다. 따라서 Canceled가 호출 되었더라도 작업이 실행 상태에있을 것입니다. – nickv