C# 为什么在使用WebClient.DownloadFileTaskAsync时某些文件会导致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

我试图使用WebClient.downloadfiletasksync从FTP服务器下载多个文件,但多次出现以下问题:多个文件最终为0KB

我尝试了不同的建议解决方案,但我无法获得所有文件。我做错了什么

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);
    
  • 使用wait
    Task.whalll(taskArray)
    而不是wait每个任务。这保证了您的所有任务都已完成

  • 学习第三方物流的一些和平;)


  • 你的日志显示了什么?预期的文件大小是多少?我在日志中没有发现任何异常,文件大小都在15k左右。如果我真的想继续处理下载的每个文件,我该怎么做?另外,如果情况是有些任务没有完成,那么通常不是后一个任务吗?我的情况完全是随机的。我想我需要回到一些TPL基础知识:/var client=new client();-这是什么?为什么不使用(var client=new WebClient())?var client是一个包含多个与FTP服务器交互的方法的类,因此client!=网络客户端。抱歉,我看到我的代码缺少类def。我会更新的。