c# - 如何在 C# 中使用线程来加快工作?

标签 c# .net multithreading ftp console-application

我在 FTP 服务器上有数千个文件。我的任务是从 ftpserver 下载文件,然后解压缩文件,然后处理文件。下载时我使用 Tamir 库,解压缩时我使用 Ionic.zip 然后处理文件。

当我使用线程时,从 FTP 服务器下载文件停止了,不知道原因,可能是 FTP 服务器不允许使用线程下载文件。然后我只使用线程来解压缩文件和进行处理。这也失败了,出现了类似

的错误

The process cannot access the file 'file ' because it is being used by another process`.

所以现在我按顺序做所有事情。代码原型(prototype)如下图

 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 个任务,这样的场景是否可能?

最佳答案

以下是您创建异步版本的代码,它可以在后台进行文件下载。您可以为 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;
}

关于c# - 如何在 C# 中使用线程来加快工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45768502/

相关文章:

c# - 如何在 C# 中读取 Http 端口?

c# - 是否可以在 IE 中使用 "autopopulate"字段?

.net - 我可以在 .NET CF 上使用什么来替代 HttpUtility.UrlEncode

c# - Monitor.Pulse 和 Monitor.Wait 之间的竞争条件?

c# - 方程比较器算法

c# - 程序运行时更改了 Dns 设置

C# 控制台?

.net - .Net 和 C++ 中的静态变量如何工作?

python - PyQt4中QWebView的多线程

ios - SpriteKit : performance hit while preloading SKTextureAtlas