2016-10-27 2 views
1

Есть ли способ получить текущую запущенную задачу по идентификатору, как только вы выйдете из метода, в котором вы начали работу? Я хотел бы получить некоторые текущие задачи, чтобы я мог остановить некоторые из них в середине исполнения, не прерывая поток программы.C# выборки асинхронных задач

Например:

class Test 
{ 
    List<Task> listOfTasks = new List<Task>(); 


    void taskCaller() 
    { 
     try 
     { 
      var myTask = Task.Factory.StartNew(()=> testMethod()); 
      listOfTasks.Add(myTask); 
     } 
     catch (System.Exception) 
     { 
      //... 
      throw; 
     } 
    } 


    void taskGetter() 
    { 
     foreach (var item in listOfTasks) 
     { 
      if(item == something) 
      { 
       item.KillExecution(); 
      } 
     } 
    } 


    private void testMethod() 
    { 
     // doing something 
     throw new NotImplementedException(); 
    } 
} 

EDIT

Я хочу сделать это без отмены токенов, если это возможно, поскольку он не работает для меня, как я хочу, потому что я бегу выборку таймера DLL из DB и токены отмены работают только в том случае, если я немедленно убиваю задачу с token.Cancel(), однако если я попробую token.CancelAfter(), это не сработает, потому что оно запускается только после завершения задачи с исполнением, какой это не идея.

EDIT2:

Не копировать тонны кода, вот псевдо всего потока:

new timer(repeat method every xx time units) 
    open DB 
    do some work 
    save DB 

Продолжая plast1k предложение ...

Когда я проверить словарь, если в этом сценарии требуется аннулирование, он говорит true, но он ничего не делает для выполняемой задачи

private void getActiveTasks() 
{ 
    if (!ListOfTasks.Any()) 
     return; 
    Console.WriteLine("Currently running:"); 
    foreach (var task in ListOfTasks) 
    { 
     Console.WriteLine("\t" + task.Key); 
     Console.WriteLine("\t" + task.Value.MyTask.Id); 
     task.Value.Token.Cancel(); 
     Console.WriteLine("\t" + task.Value.Token.IsCancellationRequested); 


     ListOfTasks.Remove(task.Key); 
     return; 
    } 
} 
+1

Не пытаясь быть придурком, но если отмена лексемы не являются работая тогда, вы делаете что-то неправильно. Может быть, вы могли бы объяснить, почему они не работают? См. [Проблема XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – Equalsk

+0

Здесь я обновил его – Norgul

+0

По-прежнему звучит так, будто вы неправильно используете маркеры отмены. Это совместное усилие, метод, который извлекает из БД, должен регулярно проверять, отменен ли переданный токен, и если он должен выйти из системы изящно. Не знаете, почему вы должны использовать CancelAfter over Cancel, особенно если вы хотите отменить как можно скорее? – Equalsk

ответ

2

Как вы, возможно, уже исследовали, на сегодняшний день единственным способом отменить задачу является уведомление об отмене с помощью отмены и уведомление об отказе. Кроме того, это предпочтительный способ сделать это также. Однако, поскольку в вашем вопросе упоминается, что вы не можете использовать источник отмены, вы можете использовать технику, упомянутую в другом ответе SO (ссылка включена).

Сущность по ссылке, Вы можете создать эти задачи и запускать их в другом потоке и прервать поток всякий раз, когда вы можете отменить задание

How do I force a Task to stop?

1

Убедитесь, что вы на самом деле обработками отмены внутри вашей задачи (через cancelToken.ThrowIfCancellationRequested()) как вызов Отмена на источнике токена отменяет планирование задач, но фактически не останавливает выполнение.

Правильный способ остановить задачу - использовать маркеры отмены. Смотрите пример здесь

https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

и здесь

https://blogs.msdn.microsoft.com/andrewarnottms/2014/03/19/recommended-patterns-for-cancellationtoken/

+0

По его вопросу кажется, что метод, который он пытается запустить, не поддерживает маркеры отмены, поэтому даже если метод оболочки не смог отменить внешний вызов. – plast1k

1

В то время как вы должны увидеть ответ usaipavan в и ссылку для правильной техники отмены для того, чтобы следить за вашими нитками или задач, которые вы могли бы просто добавьте их в словарь вместо списка и назначьте идентификатор по вашему выбору. Это может быть целое число или строка или что-то еще, в этом примере это GUID.

Dictionary<Guid, Task> listofTasks = new Dictionary<Guid, Task>(); 

public Guid StartTask() 
{ 
    Task myTask = Task.Factory.StartNew(()=> testMethod()); 
    Guid taskID = Guid.NewGuid(); 
    listOfTasks.Add(taskID, myTask); 
    return taskID; 
} 

public void CancelTask(Guid id) 
{ 
    // listOfTasks[id].choose_your_own_task_cancellation_adventure() 
} 

Если вы можете использовать маркеры отмены вы можете сохранить их в словаре/другой словарь/в виде кортежа. Если вы хотите, чтобы определить группы этих задач (т.е., отменить все из запрашивает операцию «DB Query») вы могли бы сделать что-то вроде этого

public class TaskWrapper 
{ 
    public TaskWrapper(string operationID, Task task, CancellationTokenSource cancellationSource) 
    { 
     this.OperationID = operationID; 
     this.Task = task; 
     this.CancellationSource = cancellationSource; 
    } 
    public string OperationID { get; set; } 
    public Task Task { get; set; } 
    public CancellationTokenSource CancellationSource { get; set; } 
} 


private Dictionary<Guid, TaskWrapper> ListOfTasks = new Dictionary<Guid, TaskWrapper>(); 


// populate the list 


public void CancelAll(string operation) 
{ 
    listOfTasks.Where(a => a.OperationID == operation).CancellationSource.Cancel(); 
} 
+0

Идея потрясающая, но я не могу заставить маркеры работать ... так как я использую таймер (смотрю редактирование), возможно ли, что токен, связанный с конкретной задачей, как-то «переусердствует» и не является дольше связан с ним, поэтому, если я отменяю его ... ничего не происходит? – Norgul

+0

Что-то вроде 'MyTask [id] .Token.Cancel()' возможно? Поэтому я непосредственно знаю, к какой задаче пересылается токен? – Norgul

+0

@Norgul Да, это возможно - см. Https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx для получения дополнительной информации о словаре. Также вы правы, что не можете использовать маркер отмены, чтобы должным образом отменить предложенный вами сценарий. – plast1k

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