raoyutian / PaddleOCRSharp

PaddleOCRSarp是一个基于百度飞桨PaddleOCR的C++代码修改并封装的.NET的OCR工具类库。包含文本识别、文本检测、表格识别功能。本项目针对小图识别不准的情况下做了优化,比飞桨原代码识别准确率有所提高。 包含总模型仅8.6M的超轻量级中文OCR,单模型支持中英文数字组合识别、竖排文本识别、长文本识别。同时支持多种文本检测。
Apache License 2.0
617 stars 100 forks source link

多线程 #28

Closed desNBA closed 9 months ago

desNBA commented 1 year ago

image

同志,目前是不是已经支持多线程了

raoyutian commented 1 year ago

支持多线程调用,但不能提高效率。内部会排队。

ZGGSONG commented 11 months ago

支持多线程调用,但不能提高效率。内部会排队。

我在使用的时候发现如果使用 Task.Run(() => DoSomething()); 不出两次必定报错,内容:

System.AccessViolationException:“Attempted to read or write protected memory. This is often an indication that other memory is corrupt.”

然而当我切换成 Thread thread = new Thread(() => DoSomeThing()); 以后就没再报错了

qaqz111 commented 10 months ago

然而当我切换成 Thread thread = new Thread(() => DoSomeThing()); 以后就没再报错了

换 Thread 的方法管用,原因我猜是因为 Task.Run() 内部是用 ThreadPool.QueueUserWorkItem 来调用线程池里面缓存的 Thread 对象执行传入委托的,委托执行结束后用过的线程对象并没有销毁,PaddleOCREngine.Dispose 调用 dll 的 FreeEngine 进行清理,可能是这货的清理没弄干净,要是运气好下次还分配到上次用过的同一个线程就没事,但是下次如果被分配了跟上次不同的线程然后在里面重新 new PaddleOCREngine 就会炸。

另外在一个线程 new 的 PaddleOCREngine 也不能在其他线程去调用 DetectXXX,也会炸。

Task.Run 的机制不确定是不是记错了,很久以前追进 Task.Run 看过,记得应该是这样。而且我自己用 ThreadPool.QueueUserWorkItem 写的线程调度来使用 PaddleOCREngine 会发生一样的错误,所以应该是这样或者类似的原因导致错误的。