Чтение многопоточного XML-файла - PullRequest
3 голосов
/ 25 июня 2011

Я много искал, но не смог найти правильного решения для моей проблемы.Я написал XML-файл, содержащий всю информацию о сериале ТВ-шоу.Это 38 КБ и содержит атрибуты и строки для около 680 переменных.Сначала я просто прочитал его с помощью XMLTextReader, который отлично работал с моим четырехъядерным процессором.Но моему жене, пятилетнему ноутбуку, потребовалось около 30 секунд, чтобы прочитать его.Поэтому я подумал о многопоточности, но получаю исключение, потому что файл уже открыт.

Начало потока выглядит следующим образом

while (reader.Read())
{
   ...
   else if (reader.NodeType == XmlNodeType.Element)
   {
       if (reader.Name.Equals("Season1"))
       {
           current.seasonNr = 0;
           current.currentSeason = season[0];
           current.reader = reader;
           seasonThread[0].Start(current);
       }
       else if (reader.Name.Equals("Season2"))
       {
           current.seasonNr = 1;
           current.currentSeason = season[1];
           current.reader = reader;
           seasonThread[1].Start(current);
       }

И метод синтаксического анализа, как этот

reader.Read();

for (episodeNr = 0; episodeNr < tmp.currentSeason.episode.Length; episodeNr++)
{
    reader.MoveToFirstAttribute();
    tmp.currentSeason.episode[episodeNr].id = reader.ReadContentAsInt();
    ...
}

Но это не работает ...

Я передаю читателю, потому что я хочу, чтобы курсор находился в правильном положении.Но я также понятия не имею, может ли это вообще сработать.

Пожалуйста, помогите!

РЕДАКТИРОВАТЬ: Ребята, где я написал о IE ??Программа, которую я написал, анализирует файл.Я запускаю его на своем компьютере и на ноутбуке.IE вообще нет.

EDIT2: Я провел некоторое исследование секундомера и выяснил, что анализ файла xml занимает всего около 200 мс на моем ПК и 800 мс на ноутбуке с жёсткими дисками.WPF работает так медленно?Что я могу сделать?

Ответы [ 4 ]

3 голосов
/ 25 июня 2011

Я согласен с большинством всех комментариев.Чтение файла размером 38 КБ не должно занимать много времени.У вас на компьютере работает что-то еще, антивирус и т. Д., Которые могут мешать обработке?

Количество времени, которое потребуется вам для создания потока, будет намного больше, чем количество времени, потраченное на чтение файла.Если бы вы могли опубликовать фактический код, использованный для чтения файла, и сам файл, это может помочь проанализировать узкие места производительности.

1 голос
/ 25 июня 2011

Я думаю, что вы не можете анализировать XML в нескольких потоках, по крайней мере, не таким образом, который принес бы выигрыш в производительности, потому что для чтения с некоторой точки в файле вам нужно знать все, что предшествует ему, если не более , чтобы знать, на каком ты уровне.

Ваш код, если бы работала синица, сделал бы что-то вроде этого:

main  season1  season2

read
read
skip   read
skip   read
read
skip             read
skip             read

Обратите внимание, что для «пропуска» необходимо полностью проанализировать XML, что означает, что вы выполняете тот же объем работы, что и раньше, в основном потоке. Разница лишь в том, что вы выполняете дополнительную работу с фоновыми потоками.

Что касается медлительности, простой анализ такого небольшого XML-файла должен быть очень быстрым. Если он медленный, вы, скорее всего, делаете что-то медленное или разбираете файл несколько раз.

0 голосов
/ 25 июня 2011

Ваша XML-схема не поддается параллелизму, поскольку у вас, кажется, есть имена узлов (Season1, Season2), которые содержат те же данные, но должны анализироваться по отдельности.Вы можете изменить схему, чтобы иметь такие же имена узлов (например, Season) и атрибуты, которые выражают различия в данных (например, Number для обозначения номера сезона).Затем вы можете распараллелить то есть используя Linq to XML и PLinq:

XDocument doc = XDocument.Load(@"TVShowSeasons.xml");
var seasonData = doc.Descendants("Season")
                    .AsParallel()
                    .Select(x => new Season()
                    {
                        Number = (int)x.Attribute("Number"),
                        Descripton = x.Value
                    }).ToList();
0 голосов
/ 25 июня 2011

Если я понимаю, как используется ваш файл .xml, вы, по сути, создали базу данных .xml.

Если все правильно, я бы порекомендовал разбить ваш Xml на разные XML-файлы с индексированным XML-документом.Я думаю, что вы можете запросить - используя Linq-2-Xml - набор данных .xml из определенного источника .xml.

Конечно, это означает, что вам все равно нужно будет загрузить файл .xml;тем не менее, вы будете загружать файлы значительно меньшего размера и сможете, хотя крайне обескураживает , асинхронно загружать объекты XML-документов.

...