2016-03-23 39 views
0

我正在将单线程应用程序转换为多线程应用程序。使用锁来控制对非线程安全库的访问

根据他们的文档,我们使用的一个库不是线程安全的。因此,要解决这个问题的答案是使用锁(至少这是我的理解至今..)

所以我踢掉我的主题:

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()实例,因此存在多个锁?

回答

0

在下面的进一步阅读: https://msdn.microsoft.com/en-us/library/3a86s51t.aspx

在特别是下列:

保护的数据。如果lockobject是一个共享变量,则专有的 锁可防止任何其他类的实例中的线程在执行SyncLock块时执行 块,而其他线程正在执行该锁。这可以保护在所有实例之间共享的 数据。

如果lockobject是一个实例变量(不共享),所述锁防止 从在同一时间在同一实例另一线程执行的SyncLock 块在当前实例中运行的线程。这个 保护由个体实例维护的数据。

因此,我修改了我的锁以共享。 这似乎解决了我的问题。

+0

虽然这可能工作,编译,而不是抛出错误。我鼓励你使用你正在转向并行的相关数据来进行性能分析。我这样说是因为对我来说,看起来你的并行代码的很大一部分将被阻塞,等待线程同步。该类的文档是否说共享了不是线程安全的实例?或者该类的单个实例不是线程安全的?如果是第二个,则可能不能使用锁并获得并行性的全部功能。 – davidallyoung

+0

谢谢大卫。文档不是很详细。它只是提到它不是线程安全的。我测试没有锁,结果是不可预测的。然而,由于已经实现了这些锁,我已经能够测试大量的数据,并且结果很好并且可以预测,并且与单线程方法相比,仍然有明显的性能提升。 – Fiona