我正在将单线程应用程序转换为多线程应用程序。使用锁来控制对非线程安全库的访问
根据他们的文档,我们使用的一个库不是线程安全的。因此,要解决这个问题的答案是使用锁(至少这是我的理解至今..)
所以我踢掉我的主题:
Parallel.ForEach(recordList, Sub(record) ProcessRecord(record))
Public Sub ProcessRecord(ByVal record As UploadRecord)
Dim controller As New UploadController()
controller.ProcessRecord(record)
End Sub
在类UploadController(),我已经添加了一个锁定对象。
private thisLock As Object = new Object()
然后我使用这个锁来控制对我的非线程安全库的调用的访问。
SyncLock (thisLock)
structureTemplatefs = IO.File.OpenRead(GetVersion(record, validationTemplatePathElement) & structureTemplateElement)
validator = New FileValidator(structureTemplatefs, record.FileData, True)
'Get all errors...
result = validator.Validate(FileValidator.ValidationEngineType.Structure, True)
End SyncLock
AND:
SyncLock thisLock
record.FileData.Seek(0, SeekOrigin.Begin)
cellValue = excelUtility.GetCellFormulaValue(record.FileData, sheetNo, GetConfigSetting(GenericConfigSection.VALIDATION_CELL_RANGE_NAME), fileName)
End SyncLock
但是,它不工作。是否因为每个线程都创建了自己的UploadController()实例,因此存在多个锁?
虽然这可能工作,编译,而不是抛出错误。我鼓励你使用你正在转向并行的相关数据来进行性能分析。我这样说是因为对我来说,看起来你的并行代码的很大一部分将被阻塞,等待线程同步。该类的文档是否说共享了不是线程安全的实例?或者该类的单个实例不是线程安全的?如果是第二个,则可能不能使用锁并获得并行性的全部功能。 – davidallyoung
谢谢大卫。文档不是很详细。它只是提到它不是线程安全的。我测试没有锁,结果是不可预测的。然而,由于已经实现了这些锁,我已经能够测试大量的数据,并且结果很好并且可以预测,并且与单线程方法相比,仍然有明显的性能提升。 – Fiona