2016-12-30 27 views
2

我正在使用Windows服務來定期檢查更新。就像一兩​​分鐘。對於這個我使用.NET 4.6.1與這是定期進行異步下載的好代碼嗎?

  1. 系統定時器,&
  2. 任務

下面是我的代碼

/// <summary> 
    /// Download updates from server 
    /// </summary> 
    /// <returns></returns> 
    private void DownloadUpdate() 
    { 
     try 
     { 
      var package = string.Empty; 
      if (_server != null) 
      { 
       timer.Stop(); 
       package = _server.Download(); 
       if (package.Length > 0) 
        _server.Install(package); 
      } 
     } 

     finally 
     { 

      timer.Start(); 

     } 

    } 

    /// <summary> 
    /// To carry out download asynchronous way 
    /// </summary> 
    private async void DowloadUpdateAsync() 
    { 
     await Task.Run(()=>DownloadUpdate()); 
    } 

只是想知道,如果它的一正確的方法來管理間隔。

+0

我不知道您的完整方案,但我想知道你爲什麼需要這是異步。如果'DownloadUpdate'是爲了異步運行,我認爲它不應該處理計時器(就像停止/啓動它),即使你每次運行一個任務。我想你想不定期地下載很多軟件包,對嗎?! – Alisson

+2

這可能更適合代碼評論網站。 http://codereview.stackexchange.com/ –

+0

@Alisson - 它必須定期檢查更新,下載時,計時器需要保持關閉狀態,並且一次只下載一個軟件包。 –

回答

0
  1. 對於async方法,返回Task如果你不希望它返回一個結果。見this link

  2. Task.Run(()=>DownloadUpdate());可以簡化爲Task.Run(DownloadUpdate);

  3. 我真的不明白爲什麼你需要用任務在async方法的任何原因。由於DownloadUpdate不是異步的,因此無論如何都會阻塞線程,您只需將其作爲Task運行即可,或者將其直接排列到線程池。

+0

因爲Run無法識別調用方法是Func 還是Action,所以Task.Run(()=> Method())不等於Task.Run(方法)。對Action的類型轉換是必要的。 –

-1

添加到陳立夫的回答是:

我建議,你應該開始在ContinueWith定時器()。

TPL使用垃圾收集器的終結機制來發現什麼時候失敗的任務已被放棄,導致例外情況是未被發現。發生這種情況時,TaskScheduler類會引發其UnobservedTaskException事件。處理你的例外情況會更好。使用ContinueWith時,這是加號。

嘗試這樣:

Timer timer = new Timer(); 
    public Program() 
    { 
     timer.Interval = 5000; 
     timer.Elapsed += DownloadUpdate; 
     timer.Enabled = true; 
    } 

    private void DownloadUpdate(object sender, ElapsedEventArgs e) 
    { 
     Task.Factory.StartNew((Action)DownloadUpdate).ContinueWith(t => 
     { 
      bool shouldTimerStartAgain = true; 
      if (t.IsFaulted) 
      { 
       // handle t.Exception 
       // Compute if this task need to stop? 
       // If so set shouldTimerStartAgain = false 
      } 
      if (shouldTimerStartAgain) 
      { 
       timer.Start(); 
      } 
     }); 
    } 

    private void DownloadUpdate() 
    { 
     var package = string.Empty; 
     if (_server != null) 
     { 
      timer.Stop(); 
      package = _server.Download(); 
      if (package.Length > 0) 
       _server.Install(package); 
     } 
    } 
+0

如果你想處理異常,那麼使用'try/catch'。你不應該像這樣使用'StartNew',也不應該使用'ContinueWith'來代替'async'方法。 – Servy

+0

@Servy你會詳細說明一下嗎? –