У меня есть прецедент, где мне нужно:
- итерация через каждый вход node в документе Xml
- выполнить расчет по времени на каждом входе и
- записать результаты в файл XML.
Ввод выглядит примерно так:
<Root>
<Input>
<Case>ABC123</Case>
<State>MA</State>
<Investor>Goldman</Investor>
</Input>
<Input>
<Case>BCD234</Case>
<State>CA</State>
<Investor>Goldman</Investor>
</Input>
</Root>
и вывод:
<Results>
<Output>
<Case>ABC123</Case>
<State>MA</State>
<Investor>Goldman</Investor>
<Price>75.00</Price>
<Product>Blah</Product>
</Output>
<Output>
<Case>BCD234</Case>
<State>CA</State>
<Investor>Goldman</Investor>
<Price>55.00</Price>
<Product>Ack</Product>
</Output>
</Results>
Я хотел бы запускать вычисления параллельно; типичный входной файл может содержать 50 000 входных узлов, а общее время обработки без потоковой передачи может составлять 90 минут. Примерно 90% времени обработки расходуется на шаге 2 (расчеты).
Я могу многократно прокручивать XmlReader параллельно:
static IEnumerable<XElement> EnumerateAxis(XmlReader reader, string axis)
{
reader.MoveToContent();
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.Name == axis)
{
XElement el = XElement.ReadFrom(reader) as XElement;
if (el != null)
yield return el;
}
break;
}
}
}
...
Parallel.ForEach(EnumerateAxis(reader, "Input"), node =>
{
// do calc
// lock the XmlWriter, write, unlock
});
В настоящее время я склонен использовать блокировку при записи в XmlWriter для обеспечения безопасности потоков.
Есть ли более элегантный способ обработки XmlWriter в этом случае? В частности, должен ли я иметь код Parallel.ForEach передать результаты обратно в исходный поток и связать этот поток с XmlWriter, избегая необходимости блокировки? Если это так, я не уверен в правильности этого подхода.