2015-01-04 2 views
4

Это может быть странный вопрос, и это действительно для моей образовательной цели, поэтому я могу применить его в будущих сценариях, которые могут возникнуть.Как определить, завершена ли Task.Run в цикле

Я использую C#.

Я испытываю стресс, так что это не совсем производственный код.

Я загружаю данные на свой сервер через веб-службу.

Я запускаю услугу с помощью Run.Task.

Я проверяю, завершена ли задача, прежде чем разрешить запуск следующей Run.Task.

Это делается в цикле.

Однако, поскольку я использую модульную заявленную задачу, не повлияет на результат? Я могу объявить локальную переменную Task.Run, но я хочу посмотреть, как далеко я могу получить этот вопрос.

Если Task.Run может поднять событие, чтобы сказать, что оно завершено, это может не быть проблемой?

Это мой код:

// модуль декларации:

private static Task webTask = Task.Run(() => { System.Windows.Forms.Application.DoEvents(); }); 

// в функцию, вызываемую с помощью таймера

if (webTask.IsCompleted) 
{ 
    //keep count of competed tasks 
} 


webTask = Task.Run(() => 
{ 
    try 
    { 
     wcf.UploadMotionDynamicRaw(bytes); //my web service 
    } 
    catch (Exception ex) 
    { 
     //deal with error 
    } 
); 
+1

Использование [Задача Продолжение] (http://msdn.microsoft.com/en-us/library/ee372288%28v=vs.110%29 .aspx). Существуют разные модификации.Один из них - сделать что-то после завершения задачи *. IMO вам не нужен таймер - измените свой код на 'webTask.ContinueWith ...'. – pasty

+0

@pasty HI, спасибо за ответный удар. Я посмотрю на это сейчас и отчитаюсь - спасибо :) –

+0

@pasty, поэтому, когда я изменяю свой код на это: –

ответ

6

IMO вам не нужен таймер. Использование Task Continuation вы подписаться к сделать событие:

System.Threading.Tasks.Task 
.Run(() => 
{ 
    // simulate processing 
    for (var i = 0; i < 10; i++) 
    { 
     Console.WriteLine("do something {0}", i + 1); 
    } 
}) 
.ContinueWith(t => Console.WriteLine("done.")); 

Выход есть:

do something 1 
do something 2 
. 
. 
do something 9 
do something 10 
done 

Ваш код может выглядеть следующим образом:

var webTask = Task.Run(() => 
{ 
    try 
    { 
     wcf.UploadMotionDynamicRaw(bytes); //my web service 
    } 
    catch (Exception ex) 
    { 
     //deal with error 
    } 
}).ContinueWith(t => taskCounter++); 

С задачей продолжения вы могли бы даже отличить не удалось и успех результат процесса, если вы хотите считать только успешные задачи - используя TaskContinuationOptrions.

+1

Привет, я использовал таймер только для стресс-тестирования и полностью согласен с вами. Пример в MSDN отличается от вашего, и я предпочитаю ваш. Гораздо яснее. Спасибо –

+0

Будете ли вы использовать downvoter, чтобы объяснить? – pasty

2

Вы можете ждать, пока вашу задачу завершить к ожидающим своей задаче как этого

await webTask; 

, который будет асинхронно ждать «webTask», чтобы закончить. Вместо таймера вы можете использовать await Task.Delay, который будет асинхронно ждать истечения задержки. Я также хотел бы сделать асинхронный вызов wcf, поэтому вам не нужно звонить внутри Task.Run. См. this question для некоторых советов.

Я бы переписать код следующим образом:

public async Task UploadAsync() 
{ 
    while(true) 
    { 
     await Task.Delay(1000); // this is essentially your timer 

     // wait for the webTask to complete asynchrnously 
     await webTask; 

     //keep count of competed tasks 

     webTask = Task.Run(() => 
         { 
          try 
          { 
           // consider generating an asynchronous method for this if possible. 
           wcf.UploadMotionDynamicRaw(bytes); //my web service 
          } 
          catch (Exception ex) 
          { 
           //deal with error 
          } 
         });  
    } 
} 
+0

Привет, спасибо за другой ответ. Очень признателен. Я знал об ожидании, но я хотел иметь асинхронный режим. Причиной всего этого является отслеживание того, поддерживает ли веб-сервер мои повторяющиеся вызовы. Наблюдая за очередью, я могу (надеюсь) обнаружить это. –

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