Câu hỏi của tôi là làm thế nào tôi có thể dừng một tác vụ chạy dài (.net 4)? Tôi đã triển khai TPL và đã thử sử dụng CancellationTokenSource nhưng dường như nó không hoạt động cho kịch bản của tôi. Tất cả các ví dụ tôi đã thấy giả sử bạn đang làm việc trong một vòng lặp while để bạn có thể kiểm tra xem tác vụ đã bị hủy hay chưa, trong khi tôi chỉ có một hoạt động duy nhất mất nhiều thời gian. Tôi không thể chờ đợi cho công việc được hoàn thành như tôi cần phải giả định nó có thể không bao giờ hoàn thành. Đây là mã tôi đã cố gắng:Tạm dừng nhiệm vụ chạy dài một cách an toàn
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.");
}
Mã này hoạt động nhưng nhiệm vụ là không bao giờ vứt bỏ nếu “timeout” xảy ra và công việc đang được thực hiện truy cập “mã không được quản lý”, tức là nguồn lực. Điều đó nói rằng IsCancelledRequested không thể được sử dụng trong Work.LongRunning() vì vậy tôi không thể ThrowIfCancellationRequested.
Tôi mở cho các ý tưởng khác cũng như tôi đã thử BackgroundWorker nhưng điều đó cũng có vẻ không phù hợp.
dụ mới:
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();
}
Cảm ơn câu trả lời! Tôi đã xem mẫu Begin \ End, nhưng sau đó kiểm tra kết quả trên End's ((Task) isyncResult) .Result bạn phải đợi cho đến khi nó hoàn thành. Tôi đã cập nhật ví dụ của mình. Khi các thuộc tính trên ServiceController dường như được tải chậm ngay khi bạn kiểm tra một giá trị có thể mất bao lâu ... –
nickv
Tôi phải thừa nhận rằng tôi không thể làm theo mã của bạn hoàn toàn nhưng tại sao bạn không thêm tiếp tục với ContinueWith ? – Stilgar
Bởi vì tôi không muốn tiếp tục với một nhiệm vụ mới. Tôi có một nhiệm vụ mà tôi muốn thực hiện, nhiệm vụ đó có thể không mang lại một phản ứng do bất cứ điều gì vì vậy nhiệm vụ sẽ ở trạng thái chạy mãi mãi mặc dù bị hủy bỏ được gọi. – nickv