2015-04-09 2 views
2

Мне нужно выполнить несколько задач внутри службы Windows, которую я пишу параллельно. Я использую VS2013, .NET 4.5, и этот поток Basic design pattern for using TPL inside windows service for C# показывает, что TPL - это путь.TPL внутри службы Windows

Ниже приводится моя реализация. Мне было интересно, может ли кто-нибудь сказать мне, правильно ли я это сделал?

public partial class FtpLink : ServiceBase 
{ 
    private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); 
    private readonly ManualResetEvent _runCompleteEvent = new ManualResetEvent(false); 

    public FtpLink() 
    { 
     InitializeComponent(); 

     // Load configuration 
     WebEnvironment.Instance.Initialise(); 
    } 

    protected override void OnStart(string[] args) 
    { 
     Trace.TraceInformation("DatabaseToFtp is running"); 

     try 
     { 
      RunAsync(_cancellationTokenSource.Token).Wait(); 
     } 
     finally 
     { 
      _runCompleteEvent.Set(); 
     } 
    } 

    protected override void OnStop() 
    { 
     Trace.TraceInformation("DatabaseToFtp is stopping"); 

     _cancellationTokenSource.Cancel(); 
     _runCompleteEvent.WaitOne(); 

     Trace.TraceInformation("DatabaseToFtp has stopped"); 
    } 

    private async Task RunAsync(CancellationToken cancellationToken) 
    { 
     while (!cancellationToken.IsCancellationRequested) 
     { 
      Trace.TraceInformation("Working"); 

      // Do the actual work 
      var tasks = new List<Task> 
      { 
       Task.Factory.StartNew(() => new Processor().ProcessMessageFiles(), cancellationToken), 
       Task.Factory.StartNew(() => new Processor().ProcessFirmware(), cancellationToken) 
      }; 

      Task.WaitAll(tasks.ToArray(), cancellationToken); 

      // Delay the loop for a certain time 
      await Task.Delay(WebEnvironment.Instance.DatabasePollInterval, cancellationToken); 
     } 
    } 
} 
+1

Это лучше спросить по адресу http://codereview.stackexchange.com/ – CindyH

+0

@CindyH, Спасибо. Я сделаю это. – WRACK

+0

В отличие от сайтов форума, мы не используем «Спасибо», «Любая помощь оценена» или подписи на [so]. См. «[Должны ли« Привет »,« спасибо », теги и приветствия удалены из сообщений?] (Http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be -removed-from-posts). –

ответ

2

Есть несколько вещей, которые я бы сделал по-другому:

  1. OnStart должны выполняться своевременно. Обычная практика заключается в том, чтобы отложить работу до фонового потока, который отвечает за выполнение фактической работы. Вы на самом деле делаете это , но блокируете этот поток с вызовом Task.Wait, который делает разгрузку на фоновый поток бесполезным, потому что выполнение становится синхронным снова.
  2. Вы используете sync over async anti-pattern, этого следует избегать. Пусть вызывающий метод вызывает работу параллельно.
  3. Я думаю, вы можете использовать ManualResetEvent наоборот. Вы обматываете свой метод RunAsync в блоке try-finally, но вы вызываете только WaitOne от OnStop. Я не совсем уверен, что вам нужен замок здесь вообще, не кажется (из вашего текущего кода), что этот код вызывается параллельно. Вместо этого вы можете сохранить Task, возвращенный RunAsync, в поле и ждать его завершения.
  4. Вы используете блокирующую версию, WaitAll. Вместо этого вы можете использовать асинхронную версию, Task.WhenAll, которую можно асинхронно ждать.
+0

Спасибо. Я все еще многому учусь о TPL. Я извлек код из шаблона Azure WorkerRole, предоставленного Microsoft. вы можете помочь мне немного больше с необходимыми изменениями, я бы очень благодарен за это. Первое, что мне нужно изменить, это «RunAsync (_cancellationTokenSource.Token) .Wait();' to »Task.Run (() => StartProcessing (_cancellationTokenSource.Token)); а затем изменить подпись метода 'private async Task RunAsync (CancellationToken cancelationToken) ' to 'private void StartProcessing (CancellationToken cancelationToken)' – WRACK

+0

Работники Azure и службы Windows различаются в том смысле, что рабочие роли не должны выходить за время жизни сервис, в то время как служба Windows должна возвращаться довольно быстро. Я пытаюсь добавить фрагмент кода завтра для реализации, которую я бы использовал для службы, надеюсь, что вы попадете на правильный путь. –

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