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

时间:2015-07-27 12:26:23

标签: c# ftp webclient

我正在尝试使用WebClient.DownloadFileTaskAsync从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);
    }
}

1 个答案:

答案 0 :(得分:0)

好像你的一些任务还没有完成。尝试这样做(我把一堆文件放到ftp时也一样)

  1. 为每个要下载的文件创建任务数组。像这样循环运行它们:

    Task[] tArray = new Task[DictToUpload.Count];
    foreach (var pair in DictToUpload)
    {
        tArray[i] = Task.Factory.StartNew(()=>{/* some stuff */});
    }
    await Task.WhenAll(tArray);
    
  2. 使用等待Task.WhenAll(taskArray)而不是等待每项任务。这可以保证您完成所有任务。

  3. 了解TPL的一些和平;)