2016-03-23 41 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