2015-07-24 3 views
1

У меня есть многопоточное приложение, и я использую this для управления процессами no.of (2). Я хочу обрабатывать файлы только для указанного времени. Ниже мой подход. Я получаю Отменен CancellationTokenSource. ошибка.Как отменить поток после таймаута

Если я не рассылаю cts.Dispose();, тогда процесс не сутулится через 10 секунд. Он продолжает обрабатывать до 1000. Может ли кто-нибудь мне помочь здесь.

Примечание: У меня 1000 файлов. Требование - это файлы процесса в течение заданного времени (10 секунд) путем управления количеством процессов (2) и сном между ними (некоторые x мс).

Ниже мой код

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(2); 
      List<Task> tasks = new List<Task>(); 
      TaskFactory factory = new TaskFactory(lcts); 
      CancellationTokenSource cts = new CancellationTokenSource(); 

      for (int i = 0; i < 1000; i++) 
      { 
       int i1 = i; 
       var t = factory.StartNew(() => 
       { 
        if (cts != null) 
         Console.WriteLine("{0} --- {1}", i1, GetGuid(cts.Token)); 
       }, cts.Token); 

       tasks.Add(t); 
      } 

      Task.WaitAll(tasks.ToArray(), 10000, cts.Token); 
      cts.Dispose(); 
      Console.WriteLine("\n\nSuccessful completion."); 
      Console.ReadLine(); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 

    private static Guid GetGuid(CancellationToken cancelToken) 
    { 
     if (cancelToken.IsCancellationRequested) 
     { 
      return Guid.Empty; 
     } 
     Thread.Sleep(TimeSpan.FromSeconds(1)); 
     return Guid.NewGuid(); 
    } 
} 
+1

Что делать, если вы измените 'CancellationTokenSource КТС = новый CancellationTokenSource()' в 'CancellationTokenSource = новый к.т.н. CancellationTokenSource (10000); '? Используете ли вы свой метод CTS .Cancel() в своем коде? – Fabjan

+0

@Fabjan, я использую ASP.NET 4.0. Не 4.5. Нет метода перегрузки для CancellationTokenSource в 4.0. Спасибо –

+0

Обновлен мой ответ – Fabjan

ответ

1

Что вы можете сделать, это можно выполнить задачу, которая изменит ваше состояние Отмена токен отменен после того, как некоторое время.

Как это:

class Program 
{ 
    public static void ProcessFiles(CancellationToken cts) 
    {    
     try 
     {     
      LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(2); 
      List<Task> tasks = new List<Task>(); 
      TaskFactory factory = new TaskFactory(lcts);     

      for (int i = 0; i < 1000; i++) 
      { 
       int i1 = i; 
       var t = factory.StartNew(() => 
       { 
        if (cts != null) Console.WriteLine("{0} --- {1}", i1, GetGuid()); 
       }, cts); 

       tasks.Add(t); 
      } 

      Task.WaitAll(tasks.ToArray()); 

      Console.WriteLine("\n\nSuccessful completion."); 
      Console.ReadLine(); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 

    static void Main(string[] args) 
    { 
     CancellationTokenSource cts = new CancellationTokenSource(); 
     Task.Factory.StartNew(() => { Thread.Sleep(10000); cts.Cancel(); }); 
     ProcessFiles(cts.Token); 
     Console.ReadKey(); 
    } 

    private static Guid GetGuid() 
    { 
     Thread.Sleep(TimeSpan.FromSeconds(1)); 
     return Guid.NewGuid(); 
    } 
} 
+0

Также я хочу использовать LimitedConcurrencyLevelTaskScheduler для управления файлами обработки. В моем примере я установил 2. I.e.) В то время я могу отправить max 2 файла. с вашим примером нет контроля над обработкой файлов. Пожалуйста, проверьте. –

+0

Просто удалите этот дополнительный 'Console.WriteLine', который я добавил. Я добавил их, чтобы показать, что в то время как токен отмены не установлен в отмененную задачу состояния. Вот почему он отображает «false» и продолжает работать. Но когда он меняется на «истину», вся вещь прекращается. Не стесняйтесь изменять этот код в соответствии с вашими потребностями. – Fabjan

+0

Спасибо, сейчас хорошо работает. Но я хочу использовать LimitedConcurrencyLevelTaskScheduler, как упоминалось выше. –