首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >远程文件同步下载

远程文件同步下载
EN

Stack Overflow用户
提问于 2013-05-09 09:50:16
回答 1查看 583关注 0票数 0

序言:学习(并记住我已经知道的) C#线程、同步和数据结构是一项自分配的纯同步任务。

故事:

假设我有一个字典<string, string>,它用某个键表示文件的路径(http),即:

代码语言:javascript
复制
foo => http://domain.tld/file1
bar => http://domain2.tld/file2

我想实现一个类,它将用两个方法实现一个接口:

代码语言:javascript
复制
String Rand();
String Get(String key);

第一种方法是从所有可用的文件中随机选择文件,Get将返回特定的文件,或者准确地说,是下载文件的本地路径。

类应该是线程安全的,因此如果有几个线程请求同一个key,或者Rand()选择相同的项,那么只有一个线程应该实际将一个文件下载到本地驱动器,或者如果已经下载了文件,就应该立即检索路径。

所以,这就是我陷入困境的地方。

我如何同步一个“下载器”,使相同的文件不会被下载两次?

如何限制同时下载的数量?

PS:我不是在问任何代码,只是数据结构、类和模式的关键字,这对这个任务是有用的。

PPS:任务是100%抽象的,所以如果你认为对需求的一些改变可以使它对我(作为一个学习者)更有趣/更有用

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-14 10:55:40

因此,满足需求并使用await/async的“下载机”类的“最终”版本是:

代码语言:javascript
复制
class Downloader
{
    private IDictionary<string, string> _map;
    private IDictionary<string, string> _storage = new ConcurrentDictionary<string, string>();
    private ConcurrentDictionary<string, Task<string>> _progress = new ConcurrentDictionary<string,Task<string>>();

    public Downloader(IDictionary<string, string> map)
    {
        _map = map ?? new Dictionary<string, string>();
    }

    public async Task<string> Get(string key)
    {
        string path;

        if (!_map.TryGetValue(key, out path))
        {
            throw new ArgumentException("The specified key wasn't found");
        }

        if (_storage.ContainsKey(key))
        {
            return _storage[key];
        }

        Task<string> task;
        if (_progress.TryGetValue(key, out task))
        {
            return await task;
        }

        task = _retrieveFile(path);

        if (!_progress.TryAdd(key, task))
        {
            return await Get(key);
        }

        _storage[key] = await task;
        return _storage[key];
    }

    private async Task<string> _retrieveFile(string path)
    {
        Console.WriteLine("Started retrieving {0}", path);
        await Task.Delay(3000);
        Console.WriteLine("Finished retrieving {0}", path);
        return path + " local path";

    }
}

包含示例输出的整个代码:http://pastebin.com/LdFvPDbQ

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16458937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档