不能将 HtmlAgilityPack 与多线程一起使用



我正在使用HtmlAgilityPackParallel.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一切正常,我该如何管理这个问题?

堆栈跟踪

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(

您正在尝试异步加载 html 到同一个 HtmlDocument 对象,几乎没有库准备好处理非静态类的异步修改,这就是(在某些部分(存在锁定的原因。我猜每次您将 HTML 加载到对象时,它都会重新启动 HTML 节点的树节点数据结构,从而搞砸一切。

如果你想解析/读取 HtmlDocument 对象异步,那么这将是一回事,但你正在主动写入 HtmlDocument 对象,这意味着乱序程序执行可能会将对象属性设置为 null,同时也尝试遍历该属性。

最新更新