我有数千个文件位于FTP服务器中。我的任务是从ftpserver下载文件,然后解压缩文件,然后处理文件。下载时我正在使用Tamir
库并解压缩我正在使用Ionic.zip
然后处理文件。
当我使用线程时,从FTP服务器下载文件停止,不知道原因,也许FTP服务器不允许使用线程下载文件。然后我只使用线程解压缩文件和进行处理。这也失败了,如
之类的错误该进程无法访问文件'file',因为它正由另一个进程使用。
所以现在我按顺序做所有事情。代码原型如下所示
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个任务将处理,这样的场景是否可能?
答案 0 :(得分: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;
}
答案 1 :(得分:2)
首先,任务不一定是线程。 (What is the difference between task and thread?)
其次,我不建议使用线程,但是Tasks
或Parallel.Foreach
,因为它们有自己的优化,除非你有通过线程实现非常具体的东西。
对于您的场景,我会这样做:创建一个类ProcessFile
,它将下载,解压缩,处理一个文件,并触发一个事件;拥有n
个ProcessFile
(例如10个)实例的可枚举/列表;管理这些ProcessFile
的类会通过添加新实例来对事件做出反应,以便您处理n
个活动文件。