C# 为什么在使用WebClient.DownloadFileTaskAsync时某些文件会导致0KB
我试图使用WebClient.downloadfiletasksync从FTP服务器下载多个文件,但多次出现以下问题:多个文件最终为0KB 我尝试了不同的建议解决方案,但我无法获得所有文件。我做错了什么C# 为什么在使用WebClient.DownloadFileTaskAsync时某些文件会导致0KB,c#,ftp,webclient,C#,Ftp,Webclient,我试图使用WebClient.downloadfiletasksync从FTP服务器下载多个文件,但多次出现以下问题:多个文件最终为0KB 我尝试了不同的建议解决方案,但我无法获得所有文件。我做错了什么 class Program { static void Main() { Setup(); // This only sets up working folders etc Task t = ProcessAsync(); t.C
class Program
{
static void Main()
{
Setup(); // This only sets up working folders etc
Task t = ProcessAsync();
t.ContinueWith(bl =>
{
if (bl.Status == TaskStatus.RanToCompletion)
Logger.Info("All done.");
else
Logger.Warn("Something went wrong.");
});
t.Wait();
}
private static void Setup() {...}
static async Task<bool> ProcessAsync()
{
var c = new Catalog();
var maxItems = Settings.GetInt("maxItems");
Logger.Info((maxItems == 0 ? "Processing all items" : "Processing first {0} items"), maxItems);
await c.ProcessCatalogAsync(maxItems);
return true; // This is not really used atm
}
}
public class Catalog
{
public async Task ProcessCatalogAsync(int maxItems)
{
var client = new Client();
var d = await client.GetFoldersAsync(_remoteFolder, maxItems);
var list = d as IList<string> ?? d.ToList();
Logger.Info("Found {0} folders", list.Count());
await ProcessFoldersAsync(list);
}
private async Task ProcessFoldersAsync(IEnumerable<string> list)
{
var client = new Client();
foreach (var mFolder in list.Select(folder => _folder + "/" + folder))
{
var items = await client.GetItemsAsync(mFolder);
var file = items.FirstOrDefault(n => n.ToLower().EndsWith(".xml"));
if (string.IsNullOrEmpty(file))
{
Logger.Warn("No metadata file found in {0}", mFolder);
continue;
}
await client.DownloadFileAsync(mFolder, file);
// Continue processing the received file...
}
}
}
public class Client
{
public async Task<IEnumerable<string>> GetItemsAsync(string subfolder)
{
return await GetFolderItemsAsync(subfolder, false);
}
public async Task<IEnumerable<string>> GetFoldersAsync(string subfolder, int maxItems)
{
var folders = await GetFolderItemsAsync(subfolder, true);
return maxItems == 0 ? folders : folders.Take(maxItems);
}
private async Task<IEnumerable<string>> GetFolderItemsAsync(string subfolder, bool onlyFolders)
{
// Downloads folder contents using WebRequest
}
public async Task DownloadFileAsync(string path, string file)
{
var remote = new Uri("ftp://" + _hostname + path + "/" + file);
var local = _workingFolder + @"\" + file;
using (var ftpClient = new WebClient { Credentials = new NetworkCredential(_username, _password) })
{
ftpClient.DownloadFileCompleted += (sender, e) => DownloadFileCompleted(sender, e, file);
await ftpClient.DownloadFileTaskAsync(remote, local);
}
}
public void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e, Uri remote, string local)
{
if (e.Error != null)
{
Logger.Warn("Failed downloading\n\t{0}\n\t{1}", file, e.Error.Message);
return;
}
Logger.Info("Downloaded \n\t{1}", file);
}
}
类程序
{
静态void Main()
{
Setup();//这只设置工作文件夹等
Task t=ProcessAsync();
t、 继续(bl=>
{
if(bl.Status==TaskStatus.RanToCompletion)
Logger.Info(“全部完成”);
其他的
Logger.Warn(“出现了问题”);
});
t、 等待();
}
私有静态无效设置(){…}
静态异步任务ProcessAsync()
{
var c=新目录();
var maxItems=Settings.GetInt(“maxItems”);
Info((maxItems==0?“正在处理所有项目”:“正在处理前{0}个项目”),maxItems);
等待c.ProcessCatalogAsync(maxItems);
return true;//这不是真正使用的atm
}
}
公共类目录
{
公共异步任务ProcessCatalogAsync(int-maxItems)
{
var client=new client();
var d=await client.GetFoldersAsync(_remoteFolder,maxItems);
var list=d作为IList??d.ToList();
Info(“找到{0}个文件夹”,list.Count());
等待处理FoldersAsync(列表);
}
专用异步任务进程FoldersAsync(IEnumerable列表)
{
var client=new client();
foreach(列表中的var mFolder.Select(folder=>_folder+“/”+folder))
{
var items=await client.GetItemsAsync(mFolder);
var file=items.FirstOrDefault(n=>n.ToLower().EndsWith(“.xml”);
if(string.IsNullOrEmpty(文件))
{
Warn(“在{0}中找不到元数据文件”,mFolder);
继续;
}
等待client.DownloadFileAsync(mFolder,file);
//继续处理收到的文件。。。
}
}
}
公共类客户端
{
公共异步任务GetItemsAsync(字符串子文件夹)
{
返回等待GetFolderItemsAsync(子文件夹,false);
}
公共异步任务GetFoldersAsync(字符串子文件夹,int-maxItems)
{
var folders=await GetFolderItemsAsync(子文件夹,true);
返回maxItems==0?文件夹:folders.Take(maxItems);
}
专用异步任务GetFolderItemsAsync(字符串子文件夹,仅限bool文件夹)
{
//使用WebRequest下载文件夹内容
}
公共异步任务DownloadFileAsync(字符串路径,字符串文件)
{
var remote=新Uri(“ftp://”+_主机名+路径+“/”+文件);
var local=\u workingFolder+@“\”+文件;
使用(var-ftpClient=new-WebClient{Credentials=new-NetworkCredential(_用户名,_密码)})
{
ftpClient.DownloadFileCompleted+=(发件人,e)=>DownloadFileCompleted(发件人,e,文件);
等待ftpClient.DownloadFileTaskAsync(远程、本地);
}
}
public void DownloadFileCompleted(对象发送方、AsyncCompletedEventArgs e、Uri远程、字符串本地)
{
如果(例如错误!=null)
{
Logger.Warn(“下载失败\n\t{0}\n\t{1}”,文件,e.Error.Message);
返回;
}
Info(“下载的\n\t{1}”,文件);
}
}
您的某些任务似乎尚未完成。尝试这样做(我在将大量文件放入ftp时也这样做)
Task[] tArray = new Task[DictToUpload.Count];
foreach (var pair in DictToUpload)
{
tArray[i] = Task.Factory.StartNew(()=>{/* some stuff */});
}
await Task.WhenAll(tArray);
Task.whalll(taskArray)
而不是wait每个任务。这保证了您的所有任务都已完成你的日志显示了什么?预期的文件大小是多少?我在日志中没有发现任何异常,文件大小都在15k左右。如果我真的想继续处理下载的每个文件,我该怎么做?另外,如果情况是有些任务没有完成,那么通常不是后一个任务吗?我的情况完全是随机的。我想我需要回到一些TPL基础知识:/var client=new client();-这是什么?为什么不使用(var client=new WebClient())?var client是一个包含多个与FTP服务器交互的方法的类,因此client!=网络客户端。抱歉,我看到我的代码缺少类def。我会更新的。