所以我已经有了这段代码,可以从REST api深入研究
XML文档的层次结构.我
posted earlier得到关于如何使其递归的建议,然后我继续并将其变为parralel.
首先,我被它的运行速度所震撼 – 它在不到12秒的时间内就下载了318个XML文档,相比之下,单线程超过10分钟 – 我真的没想到会获得那么多.是否有一些问题,因为它看起来好得令人难以置信?
其次,我怀疑这段代码正在实现一个共同的模式,但可能是非“惯用”的方式.我发生了一种“生产者 – 消费者队列”,有两个独立的锁定对象.有没有更标准的方法可以做到这一点?
码.
public class ResourceGetter { public ResourceGetter(ILogger logger,string url) { this.logger = logger; this.rootURL = url; } public List<XDocument> GetResources() { GetResources(rootURL); while (NumTasks() > 0) RemoveTask().Wait(); return resources; } void GetResources(string url) { logger.Log("Getting resources at " + url); AddTask(Task.Factory.StartNew(new Action(() => { var doc = XDocument.Parse(GetXml(url)); if (deserializer.CanDeserialize(doc.CreateReader())) { var rl = (resourceList)deserializer.Deserialize(doc.CreateReader()); foreach (var item in rl.resourceURL) { GetResources(url + item.location); } } else { logger.Log("Got resource for " + url); AddResrouce(doc); } }))); } object resourceLock = new object(); List<XDocument> resources = new List<XDocument>(); void AddResrouce(XDocument doc) { lock (resourceLock) { logger.Log("add resource"); resources.Add(doc); } } object taskLock = new object(); Queue<Task> tasks = new Queue<Task>(); void AddTask(Task task) { lock (taskLock) { tasks.Enqueue(task); } } Task RemoveTask() { lock (taskLock) { return tasks.Dequeue(); } } int NumTasks() { lock (taskLock) { logger.Log(tasks.Count + " tasks left"); return tasks.Count; } } ILogger logger; XmlSerializer deserializer = new XmlSerializer(typeof(resourceList)); readonly string rootURL; }
解决方法
只是随便,我不打扰管理任务列表,所有锁定和NumTasks()方法的代码.使用
CountdownEvent会更简单,开始时是线程安全的.只需在创建新任务时递增它,并在任务完成时递减它,就像你现在正在做但没有锁定.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。