長時間実行されているタスク (.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();
}