Tôi có một nhiệm vụ khởi chạy một số nhiệm vụ con. (ví dụ: Tác vụ A tạo B, C, D, E, F). Tôi cũng tạo một System.Threading.Timer
để thăm dò ý kiến một cơ sở dữ liệu cứ sau 10 giây để kiểm tra xem mục đã lên lịch đã bị hủy bỏ theo yêu cầu chưa. Nếu có, nó đặt CancellationTokenSource
để tác vụ biết hủy. Mỗi tiểu nhiệm vụ, trong trường hợp này B, C, D, E, F, sẽ hủy bỏ khi thích hợp (chúng được lặp đi lặp lại các tập tin và di chuyển chúng xung quanh).Khi nào cần vứt bỏ System.Threading.Task với nhiệm vụ con?
Kể từ Task
cụ IDisposable
, tôi muốn biết nếu nó là một ý tưởng tốt để gọi Task.WaitAll
một lần nữa từ khối catch
, để chờ cho hủy để tuyên truyền. Trong khi yêu cầu hủy sẽ được xử lý, các tiểu nhiệm vụ có thể ở giữa một vòng lặp và không thể hủy bỏ cho đến khi hoàn thành
Tuy nhiên, theo MSDN:
Luôn gọi Dispose trước khi bạn phát hành của bạn tham chiếu cuối cùng cho Tác vụ. Nếu không, các tài nguyên mà nó đang sử dụng sẽ không được giải phóng cho đến khi bộ thu gom rác gọi phương thức Finalize của đối tượng Task.
Tôi có nên gọi lại lần nữa trên mảng nhiệm vụ của mình để gọi đúng Dispose()
trên mỗi tác vụ trong mảng không?
public class MyCancelObject
{
CancellationTokenSource Source { get;set;}
int DatabaseId { get;set;}
}
private void CheckTaskCancelled(object state)
{
MyCancelObject sourceToken = (MyCancelObject)state;
if (!sourceToken.CancelToken.IsCancellationRequested)
{
//Check database to see if cancelled -- if so, set to cancelled
sourceToken.CancelToken.Cancel();
}
}
private void SomeFunc()
{
Task.StartNew(() =>
{
MyCancelObject myCancelObject = new MyCancelObject(
databaseId,
new CancellationTokenSource());
System.Threading.Timer cancelTimer = new Timer(
new TimerCallback(CheckIfTaskCancelled),
myCancelObject,
10000,
10000);
Task[] someTasks = new Task[someNumberOfTasks];
for (int i = 0; i < someNumberOfTasks; i++)
someTasks[i] = Task.Factory.StartNew(
() =>
{
DoSomeWork(someObject, myCancelObject.CancelToken.Token);
},
TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning,
myCancelObject.CancelToken.Token);
try
{
Task.WaitAll(someTasks, cts);
}
catch (AggregateException)
{
//Do stuff to handle
}
catch (OperationCanceledException)
{
//Should I call Task.WaitAll(someTasks) again??
//I want to be able to dispose.
}
}
}
Tôi đã kiểm tra một số mã và thấy rằng 'Task.WaitAll' có thể được gọi lại để đợi các tác vụ vẫn đang chạy. Sau đó, chúng có thể được xử lý. Tôi vẫn muốn biết nếu có những cách khác để xử lý này mặc dù. –
Nó không chỉ chấp nhận được câu hỏi của riêng bạn, nhưng nó được khuyến khích. Vui lòng đăng câu trả lời và chấp nhận câu trả lời nếu bạn cảm thấy như bạn đã tìm ra. –