2014-05-16 44 views
-7

它的代碼將以15分鐘的間隔執行4個線程。上一次我運行它,前15分鐘被快速複製(6分鐘內20個文件),但第二個15分鐘慢得多。這是偶發事件,我想確定一下,如果存在瓶頸,它就會受到遠程服務器的帶寬限制。此代碼是否有瓶頸或資源密集?

編輯:我正在監視最後一次運行和15:00和:45每個8分鐘複製。 15:尚未完成,也沒有:30,兩者都至少在10分鐘前開始:45。

這裏是我的代碼:

static void Main(string[] args) 
{ 

    Timer t0 = new Timer((s) => 
    { 
     Class myClass0 = new Class(); 
     myClass0.DownloadFilesByPeriod(taskRunDateTime, 0, cts0.Token); 
     Copy0Done.Set(); 
    }, null, TimeSpan.FromMinutes(20), TimeSpan.FromMilliseconds(-1)); 

    Timer t1 = new Timer((s) => 
    { 
     Class myClass1 = new Class(); 
     myClass1.DownloadFilesByPeriod(taskRunDateTime, 1, cts1.Token); 
     Copy1Done.Set(); 
    }, null, TimeSpan.FromMinutes(35), TimeSpan.FromMilliseconds(-1)); 

    Timer t2 = new Timer((s) => 
    { 
     Class myClass2 = new Class(); 
     myClass2.DownloadFilesByPeriod(taskRunDateTime, 2, cts2.Token); 
     Copy2Done.Set(); 
    }, null, TimeSpan.FromMinutes(50), TimeSpan.FromMilliseconds(-1)); 

    Timer t3 = new Timer((s) => 
    { 
     Class myClass3 = new Class(); 
     myClass3.DownloadFilesByPeriod(taskRunDateTime, 3, cts3.Token); 
     Copy3Done.Set(); 
    }, null, TimeSpan.FromMinutes(65), TimeSpan.FromMilliseconds(-1)); 

} 

public struct FilesStruct 
{ 
    public string RemoteFilePath; 
    public string LocalFilePath; 
} 

Private void DownloadFilesByPeriod(DateTime TaskRunDateTime, int Period, Object obj) 
{ 

    FilesStruct[] Array = GetAllFiles(TaskRunDateTime, Period); 
    //Array has 20 files for the specific period. 

    using (Session session = new Session()) 
    { 
     // Connect 
     session.Open(sessionOptions); 
     TransferOperationResult transferResult; 
     foreach (FilesStruct u in Array) 
     { 
      if (session.FileExists(u.RemoteFilePath)) //File exists remotely 
      { 
       if (!File.Exists(u.LocalFilePath)) //File does not exist locally 
       { 
        transferResult = session.GetFiles(u.RemoteFilePath, u.LocalFilePath); 
        transferResult.Check(); 
        foreach (TransferEventArgs transfer in transferResult.Transfers) 
        { 
         //Log that File has been transferred 
        } 
       } 
       else 
       { 
        using (StreamWriter w = File.AppendText(Logger._LogName)) 
        { 
         //Log that File exists locally 
        } 
       } 

      } 
      else 
      { 
       using (StreamWriter w = File.AppendText(Logger._LogName)) 
       { 
        //Log that File exists remotely 
       } 
      } 
      if (token.IsCancellationRequested) 
      { 
       break; 
      } 
     } 
    } 
} 
+1

您是否嘗試啓用會話日誌記錄('Session.SessionLogPath')並檢查日誌?我不認爲你會發現任何使用定時器的東西。 –

回答

-2

問題是sftp客戶端。

控制檯應用程序的目的是循環訪問列表<>並下載文件。我嘗試過使用winscp,儘管它做了這個工作,但速度很慢。我也測試了sharpSSH,它甚至比winscp慢。

我終於結束了使用SSH。至少在我個人的情況下,它比winscp和sharpssh要快得多。我認爲winscp的問題在於我完成後沒有明顯的斷開連接方式。通過ssh.net,我可以在每次下載文件後連接/斷開連接,這是winscp無法做到的。

2

東西是不完全正確這裏。首先,你要設置4個定時器並行運行。如果你想一想,就沒有必要。你不需要4個線程始終並行運行。你只需要以特定的時間間隔啓動任務。那麼你需要多少個定時器?一。

第二個問題是爲什麼TimeSpan.FromMilliseconds(-1)?那是什麼目的?我無法弄清楚爲什麼你把它放在那裏,但我不會。

第三個問題,與多編程無關,但我應該指出,無論如何,您是每次創建一個新實例Class,這是不必要的。如果在你的課堂中,你需要設置構造函數和你的邏輯以某種順序訪問不同的方法或類的字段,這將是必要的。在你的情況下,你想要做的就是調用該方法。所以你不需要每次都有一個新的類實例。你只需要讓你調用的方法是靜態的。

這裏是我會做什麼:

  1. 商店,你需要在一個數組/列表<下載的文件>。你難道不知道你每次都在做同樣的事嗎?爲什麼要爲此編寫4個不同版本的代碼?這是不必要的。將項目存儲在數組中,然後在通話中更改索引!
  2. 以5秒爲間隔設置定時器。當它達到20分鐘/ 35分鐘/等標誌時,產生一個新線程來完成任務。這樣,即使前一個任務沒有完成,新任務也可以開始。
  3. 等待所有線程完成(終止)。當他們這樣做時,檢查他們是否拋出異常,並處理它們/必要時記錄它們。
  4. 一切完成後,終止程序。

對於第2步,如果您使用的是.NET 4.5,則可以選擇使用新的async關鍵字。但是,如果您手動使用線程,它不會產生顯着的差異。

爲什麼它這麼慢...爲什麼你不使用任務管理器檢查你的系統狀態? CPU處於高位運行狀態還是網絡吞吐量被別的東西佔用?你可以從那裏輕鬆地告訴答案。

+0

我不確定你的意思:我正在將文件存儲在數組中。我也沒有看到這4個版本的代碼。關於'Class'的4個定時器和4個實例,這是試圖查看是否有任何改進的結果。 「類」最初是靜態的。最後,問題在於我使用的sftp客戶端。 – vmgmail

+0

你沒看到...你正在使用四個定時器,通過複製和粘貼每個定時器的代碼?這裏有兩個問題:首先你有四個代碼段完全相同(你只是切換變量,它們仍然是相同的代碼);第二是有四個定時器。正如我所解釋的,你只需要一個。 – kevin

+0

正如我所提到的,我嘗試過使用4個定時器(和'Class'的4個實例)來看看我能否看到任何改進。另外,'DownloadFilesByPeriod'正在被不同的參數調用。 – vmgmail