7

У меня есть класс, который порождает различные задачи, которые могут выполняться неопределенно долго. Когда этот объект расположен, я хочу остановить выполнение этих задач.Отмена задач в методе Dispose

Является ли это правильный подход:

public class MyClass : IDisposable 
{ 
    // Stuff 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      queueCancellationTokenSource.Cancel(); 
      feedCancellationTokenSource.Cancel(); 
     } 
    } 
} 

ответ

12

Вы находитесь на правильном пути. Однако я предлагаю дождаться завершения задачи перед возвратом из метода Dispose, чтобы избежать условий гонки, когда задача продолжает работать после того, как объект был удален. Также удалите CancellationTokenSource.

public class MyClass : IDisposable 
{ 
    private readonly CancellationTokenSource feedCancellationTokenSource = 
     new CancellationTokenSource(); 
    private readonly Task feedTask; 

    public MyClass() 
    { 
     feedTask = Task.Factory.StartNew(() => 
     { 
      while (!feedCancellationTokenSource.IsCancellationRequested) 
      { 
       // do finite work 
      } 
     }); 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      feedCancellationTokenSource.Cancel(); 
      feedTask.Wait(); 

      feedCancellationTokenSource.Dispose(); 
      feedTask.Dispose(); 
     } 
    } 
} 
+0

Отличный ответ - спасибо. Один вопрос: почему вы распоряжаетесь этой задачей? – davenewza

+2

Просто потому, что это безопасно, так как вам гарантировано, что эта задача закончится к тому времени. Но [вам действительно не нужно] (http://blogs.msdn.com/b/pfxteam/archive/2012/03/25/10287435.aspx). – Douglas

+0

Хорошо отлично. Спасибо за чтение. – davenewza

Смежные вопросы