2017-08-19 64 views
0

我有數以千計的文件位於FTP服務器。我的任務是從ftpserver下載文件,然後解壓縮文件,然後處理文件。對於下載我使用Tamir庫和解壓縮我使用Ionic.zip然後處理文件。如何通過在c#中使用線程來加緊工作?

當我使用的線程,下載從FTP服務器的文件停止,不知道其中的原因,也許FTP服務器不允許使用線程下載文件。然後我使用線程來解壓縮文件並進行處理。這也因爲錯誤而失敗,如

進程無法訪問文件'文件',因爲它正在被另一個進程使用。

所以現在我正在依次做的一切。代碼原型如下圖所示

static void Main(string[] args) 
     { 
      string FTPpah = "d://Testpath"; 
      DonloadUnzipProcessFile(FTPpah); 
     } 

     private static void DonloadUnzipProcessFile(string FTPpah) 
     { 
      string Localpath = @"e://testpath"; 
      //Using Tamir libraryr 
      DownloadFile(FTPpah,Localpath); 
      //Ionic.zip library 
      UnzipFile(Localpath); 
      //c#code 
      ProcessFile(Localpath); 
     } 

有沒有什麼辦法可以提高使用ThreadsProcess這項任務?

編輯

從FTP服務器上下載不能用線程來完成?如果是這樣,我想通過使用任務解壓縮和處理。因此,我將創建10個任務(TPL),每個任務需要10個文件並解壓縮,然後執行10個任務,這樣的情況有可能嗎?

+2

搜索TPL數據流 –

+2

塔米爾/ SharpSSH庫是SFTP庫,而不是一個FTP庫。這是完全不同的東西+這是一個死了的項目,不會維持多年。不要使用它! –

+2

異步等待是要走的路,這樣的IO操作,不得在線程完成,會降低系統的可擴展性 –

回答

2

繼必是你的代碼來創建異步版本,它可以做後臺文件下載。你可以做1000個文件,它永遠不會堵塞系統,會有非常高的吞吐量,因爲一切都會發生在後臺,並且會非常快。

async Task Main() 
{ 
    // List of FTP Path and Local file Path for processing 
    var ftpFilesForProcessing = new Dictionary<string, string> 
    { 
     {"Ftp_Path_1","Local_Path_1"}, 
     {"Ftp_Path_2","Local_Path_2"}, 
     {"Ftp_Path_3","Local_Path_3"}, 
    }; 

    // FTP Files with Task for Async processing 
    var ftpFilesTaskForProcessing = new Dictionary<string, Task<string>>(); 

    // Add a relevant Task to each file processing 
    foreach (var file in ftpFilesForProcessing) 
     ftpFilesTaskForProcessing[file.Key] = FtpRead(file.Key,file.Value); 

    // All the FTP downloads will be processed here Asynchronously, then it 
     will proceed with the remaining logic 
    await Task.WhenAll(ftpFilesTaskForProcessing.Values); 

    // Unzip All files Asynchronously 

    // Process Data using Task Parallel Library  
} 

// Read the Ftp file to a local file 
public async Task<string> FtpRead(string ftpPath, string localPath) 
{ 
    // Create FTP Request object 
    FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(ftpPath); 

    // Set FTP Request Object properties 
    ftpRequest.KeepAlive = false; 
    ftpRequest.UseBinary = true; 
    ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile; 

    // This example assumes the FTP site uses anonymous logon. 
    ftpRequest.Credentials = new NetworkCredential("<Username>", "<Password>"); 

    var ftpWebResponse = await ftpRequest.GetResponseAsync(); 

    Stream ftpResponseStream = ((FtpWebResponse)ftpWebResponse).GetResponseStream(); 

    StreamReader ftpStreamReader = new StreamReader(ftpResponseStream); 

    StreamWriter ftpStreamWriter = new StreamWriter(localPath); 

    var fileData = await ftpStreamReader.ReadToEndAsync(); 

    await ftpStreamWriter.WriteAsync(fileData); 

    ftpStreamReader.Close(); 
    ftpResponseStream.Close(); 

    return localPath; 
} 
+0

我會對此進行研發 – peter

2

首先,任務不一定是線程。 (What is the difference between task and thread?

其次,我不會推薦使用線程,但TasksParallel.Foreach,因爲他們有自己的優化,除非你有一些非常具體的東西通過線程實現。

對於您的情況,我會做到這一點:創建一個類ProcessFile將下載,解壓縮,處理一個文件,並觸發事件;有一個n(比如10)ProcessFile的Enumerable/List列表;將管理這些ProcessFile的類將通過添加新實例來對事件作出反應,以便保持正在處理的活動文件的n

好運

相關問題