Imports System.IO
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Collections.Concurrent
Imports Excel = Microsoft.Office.Interop.Excel
Public Class TestCarDatas
Public Property RowID As Integer
Public Property ModelYear As Integer
Public Property VehMfcName As String
Public Property EmgVeh As Boolean
End Class
Module ExcelParallelDataGather2
Public Const ExcelVehDataPath As String = "D:\Users\Dell\Desktop"
Public rwl As New System.Threading.ReaderWriterLock()
Public rwl_writes As Integer = 0
Public FullTestVehData As New List(Of TestCarDatas)()
Public x1App As New Excel.Application
Public x1Workbook As Excel.Workbook
Public x1Worksheet1 As Excel.Worksheet
Public x1WkshtLrow As Integer
Sub main()
x1App.Visible = False
ErrorNotify = False
Console.WriteLine("Excel Parallel foreach operation program....")
Dim cki As ConsoleKeyInfo
x1Workbook = x1App.Workbooks.Open(Path.Combine(ExcelVehDataPath, "TestCarDatabase2014.xls"), , True)
x1Worksheet1 = x1Workbook.Sheets(1)
Do
Console.WriteLine("Press escape key to exit, 'a' key to reiterate, 'c' key to clear console")
cki = Console.ReadKey()
If Chr(cki.Key).ToString = "A" Then
Console.WriteLine("--> Processing...")
FullTestVehData.Clear()
rwl_writes = 0
Parallel.ForEach(Partitioner.Create(11, x1WkshtLrow + 1), _
Function()
' Initialize the local states
Return New List(Of TestCarDatas)()
End Function, _
Function(partrange, loopState, localState)
' Accumulate the thread-local computations in the loop body
localState = populateCardata(x1Worksheet1, partrange.Item1, partrange.Item2)
Return (localState)
End Function, _
Sub(finalstate)
' Combine all local states
Try
rwl.AcquireWriterLock(Timeout.Infinite)
Try
' It is safe for this thread to read or write
' from the shared resource in this block
FullTestVehData.AddRange(finalstate)
Interlocked.Increment(rwl_writes)
Finally
' Ensure that the lock is released.
rwl.ReleaseWriterLock()
End Try
Catch ex As ApplicationException
' The writer lock request timed out.
End Try
End Sub)
End If
If Chr(cki.Key).ToString = "C" Then
Console.Clear()
Console.WriteLine("Excel Parallel foreach operation program....")
End If
If Chr(cki.Key).ToString <> "A" And Chr(cki.Key).ToString <> "C" And _
cki.Key <> ConsoleKey.Escape Then
Console.WriteLine("")
Console.WriteLine("Invalid response via key press")
End If
Loop While (cki.Key <> ConsoleKey.Escape)
End Sub
Friend Function populateCardata(ByVal WksheetObj As Excel.Worksheet, ByVal rngStart As Integer, _
ByVal rngStop As Integer) As List(Of TestCarDatas)
Dim wkrng(12) As String
Dim PartVehData As New List(Of TestCarDatas)
PartVehData.Clear()
For i As Integer = rngStart To rngStop - 1
Dim data As New TestCarDatas
For j As Integer = 0 To 12
wkrng(j) = WksheetObj.Cells(i, j + 1).Address(RowAbsolute:=False, ColumnAbsolute:=False)
Next
With data
.RowID = i
.ModelYear = WksheetObj.Range(wkrng(0)).Value2
.VehMfcName = WksheetObj.Range(wkrng(1)).Value2
If WksheetObj.Range(wkrng(11)).Value2 = "Y" Then
.EmgVeh = True
Else
.EmgVeh = False
End If
End With
PartVehData.Add(data)
Next
Return PartVehData
End Function
End Module
我试图使用并行foreach和range Partitioner获取Excel工作表数据,在线程本地存储中创建列表,最后使用synclock或reader-writer锁等线程安全方法添加它们
工作表中从11行到最后一行的行将被读取并填充在列表中(T)
当我执行上面的代码
为什么会出现这种现象?
使用并行foreach的解决方案是什么,如果我在第一次运行/迭代期间需要正确的结果,而不管是否。工作表中的行数?