Невозможно использовать HtmlAgilityPack с многопоточностью - PullRequest
0 голосов
/ 22 мая 2018

Я использую HtmlAgilityPack с Parallel.Invoke, в частности, у меня есть класс с именем Table, который содержит эту реализацию:

public class Table
{
   HtmlDocument doc = new HtmlDocument();

   public void Foo1()
   {
       doc.LoadHtml("some html");
   } 

   public void Foo2()
   {
       doc.LoadHtml("some html");
   } 

   public void Foo3()
   {
        doc.LoadHtml("some html");
   } 
} 

Теперь проблема в том, что если я делаю это:

 Table table = new Table();

 Parallel.Invoke(
  () => table.Foo1(),
  () => table.Foo2(),
  () => table.Foo3());

Я получу:

непредвиденная ошибка

исключение из HtmlAgilityPack, в частности, для третьего метода.Я вижу, что в то же время объект используется двумя другими методами (конечно, я использую Parallel).

Если я вызываю метод без Parallel, все работает хорошо, как я могурешить эту проблему?

Stacktrace :

at HtmlAgilityPack.HtmlNodeCollection.Append(HtmlNode node) in C:\Users\Jonathan\Desktop\Z\zzzproject\HtmlAgilityPack\HtmlAgilityPack.Shared\HtmlNodeCollection.cs:line 321 at HtmlAgilityPack.HtmlNode.AppendChild(HtmlNode newChild) in C:\Users\Jonathan\Desktop\Z\zzzproject\HtmlAgilityPack\HtmlAgilityPack.Shared\HtmlNode.cs:line 818 at HtmlAgilityPack.HtmlDocument.PushNodeEnd(Int32 index, Boolean close) in C:\Users\Jonathan\Desktop\Z\zzzproject\HtmlAgilityPack\HtmlAgilityPack.Shared\HtmlDocument.cs:line 1882 at HtmlAgilityPack.HtmlDocument.Parse() in C:\Users\Jonathan\Desktop\Z\zzzproject\HtmlAgilityPack\HtmlAgilityPack.Shared\HtmlDocument.cs:line 1424 at HtmlAgilityPack.HtmlDocument.Load(TextReader reader) in C:\Users\Jonathan\Desktop\Z\zzzproject\HtmlAgilityPack\HtmlAgilityPack.Shared\HtmlDocument.cs:line 706 at HtmlAgilityPack.HtmlDocument.LoadHtml(String html) in C:\Users\Jonathan\Desktop\Z\zzzproject\HtmlAgilityPack\HtmlAgilityPack.Shared\HtmlDocument.cs:line 752 at SWP.Controllers.TableController.GetAttendanceTable(Int32 seasonId, Int32 competitionId, Int32 roundId, Int32 groupId)

1 Ответ

0 голосов
/ 23 мая 2018

Вы пытаетесь загрузить html в один и тот же объект HtmlDocument асинхронно, почти никакие библиотеки не готовы обработать асинхронную модификацию нестатического класса, поэтому (в некоторой части) существует блокировка.Я предполагаю, что каждый раз, когда вы загружаете HTML в объект, он перезапускает структуру данных узлов дерева узлов HTML и, таким образом, все портит.

Если вы хотите разобрать / прочитать асинхронный объект HtmlDocument, тогда это будет одинно вы активно пишете объекту HtmlDocument, что означает, что выполнение программы не по порядку может установить для свойства объекта значение null, одновременно пытаясь выполнить итерацию по этому свойству.

...