我在 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);
}
有什么方法可以通过使用 Threads
或 Process
来改进这个任务?
编辑
从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/