我从未在c#中尝试过并行编程。 所以,在我跳入之前,我希望我能得到一个快速的答案,知道是否值得深入研究它。 我有.NET 4.0的C#WCF Web服务应用程序。 (如果并行编程有效,则可以升级到4.5)
所有服务都是REST服务。 有一项服务特别需要很长时间。 该服务正在处理和修改xml文档。 服务接受xml字符串作为输入,并返回修改后的xml文件。
该服务确实在不同的位置和不同的元素处理xml。 所以,我创建了一个继承自名为IDocumentProcessor的接口的类,我有一个列表
代码简要如下
interface IDocumentProcessor {
void Process(XDocument doc);
}
public class DateProcessor : IDocumentProcessor
{
public void Process(XDocument doc) {....};
}
public class CountryProcessor : IDocumentProcessor
{
public void Process(XDocument doc) {....};
}
public class AddressProcessor : IDocumentProcessor
{
public void Process(XDocument doc) {....};
}
public class AuthorProcessor : IDocumentProcessor
{
public void Process(XDocument doc) {....};
}
....
Public class DocumentProcessorService
{
public class ProcessDocument(string xmlFileAsString)
{
var processorList = new List<IDocumentProcessor>{
new DateProcessor();
new CountryProcessor();
new AddressProcessor();
new AuthorProcessor();
}
var xDocument = XDocument.Parse(xmlFileAsString);
processorList.forEach(x => x.Process(xDocument));
}
}
所以我的快速问题,在我深入研究这个并行之前: 并行计算可以修改相同的xDocument对象(在不同的位置)
并且可以将此代码转换为使用.net 4.0进行并行计算吗?
答案 0 :(得分:3)
来自XElement文档:
线程安全 此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的。不保证任何实例成员都是线程安全的。
它基本上意味着您无法并行修改XDocument。
另一个问题是,对同一数据的某种操作进行分叉是不切实际的。
这种方式不可扩展。
对于每个CPU内核,fork可能没有足够的操作类型,并且一种类型可能比另一种更快地完成。争论也很高。
如果您的文档包含类似方案的高级元素集合,您可以并行处理它们的副本,然后用新的副本替换旧的副本。
重新组装操作必须在一个线程中完成,如果选择正确的粒度级别,则不应太昂贵。
您基本上需要为每个要处理的XElement创建一个复制构造函数。
var newElements = collectionElement.Elements().Select(el=>
Process(new XElement(el))).AsParallel();
var newCollection = new XElement("items", newElements);
答案 1 :(得分:0)
可以多个线程同时修改XDocument
的实例 - 是的,没有明确停止线程进行更改(与WinForms / WPF中的UI操作不同)。 / p>
但由于XDocument
类型不是线程安全类,因此结果完全不可预测。
正确的实现应该阻止对相同XDocument
的并行访问(即使用lock
访问操作),只要访问被序列化,您就可以从任何线程更改它。