简体   繁体   English

使用WebClient.DownloadFileTaskAsync时,为什么有些文件导致0KB

[英]Why do some files result in 0KB when using WebClient.DownloadFileTaskAsync

I'm trying to download multiple files from an FTP server using WebClient.DownloadFileTaskAsync and repeatedly have the issue that several files end up being 0KB. 我正在尝试使用WebClient.DownloadFileTaskAsync从FTP服务器下载多个文件,并反复出现几个文件最终为0KB的问题。

I've tried different suggested solutions but I just don't manage to get all files. 我尝试了不同的建议解决方案,但我没有设法获取所有文件。 What am I doing wrong? 我究竟做错了什么?

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);
    }
}

Seems like some of your tasks aren't completed. 好像你的一些任务没有完成。 Try do like this (I do the same when putting bunch of files to ftp) 尝试这样做(我把一堆文件放到ftp时也这样做)

  1. Create array of tasks for every file being downloaded. 为每个正在下载的文件创建任务数组。 Run them in cycle like this: 像这样循环运行它们:

     Task[] tArray = new Task[DictToUpload.Count]; foreach (var pair in DictToUpload) { tArray[i] = Task.Factory.StartNew(()=>{/* some stuff */}); } await Task.WhenAll(tArray); 
  2. Use await Task.WhenAll(taskArray) instead of await each task. 使用await Task.WhenAll(taskArray)而不是等待每个任务。 This guarantees all your tasks are completed. 这可以保证您完成所有任务。

  3. Learn some peace of TPL ;) 学习TPL的和平;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM