这是一个问题的后续跟进 .net file random access recoard locking
我已经能够使读取和编组工作正常,但是使用Fileget()时性能要慢得多。
有一些文章围绕,例如https://msdn.microsoft.com/en-us/library/ff647812.aspx
但遗憾的是,我们不得不使用非Blittable实体,并且他们没有提供有关如何提高性能的工作示例。
正在使用的当前代码示例:
<StructLayout(LayoutKind.Sequential, _
CharSet:=Runtime.InteropServices.CharSet.Ansi, Pack:=1)>
Structure SALbchCX 'SAL555
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
<VBFixedString(1)> Public XJ1s As Char() 'H/D
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)>
<VBFixedString(8)> Public XJ2s As Char() '
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)>
<VBFixedString(8)> Public XJ3s As Char() '
<MarshalAs(UnmanagedType.R4, SizeConst:=4)>
Public XJ4 As Single
Public XJ5 As Single
<MarshalAs(UnmanagedType.R8, SizeConst:=8)>
Public XJ6d As Double
<MarshalAs(UnmanagedType.R4, SizeConst:=4)>
Public XJ7 As Single
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=61)>
<VBFixedString(61)> Public XJ8s As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
<VBFixedString(1)> Public XJ8bs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
<VBFixedString(1)> Public XJ8cs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
<VBFixedString(1)> Public XJ8ds As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
<VBFixedString(1)> Public XJ8es As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
<VBFixedString(1)> Public XJ8fs As Char()
<MarshalAs(UnmanagedType.I4, SizeConst:=4)>
Public XJ8Al As Integer
<MarshalAs(UnmanagedType.R4, SizeConst:=4)>
Public XJ9 As Single
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=11)>
<VBFixedString(11)> Public XJAs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=30)>
<VBFixedString(30)> Public XJAAs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=9)>
<VBFixedString(9)> Public XJBs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=35)>
<VBFixedString(35)> Public XJBBs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=5)>
<VBFixedString(5)> Public XJCs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=7)>
<VBFixedString(7)> Public XJDs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)>
<VBFixedString(8)> Public XJDas As Char()
<MarshalAs(UnmanagedType.R4, SizeConst:=4)>
Public XJE As Single
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
<VBFixedString(1)> Public XJFs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)>
<VBFixedString(6)> Public XJGs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=30)>
<VBFixedString(30)> Public XJHs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=30)>
<VBFixedString(30)> Public XJIs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=30)>
<VBFixedString(30)> Public XJJs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=30)>
<VBFixedString(30)> Public XJKs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=35)>
<VBFixedString(35)> Public XJKKs As Char()
<MarshalAs(UnmanagedType.R4, SizeConst:=4)>
Public XJL As Single
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
<VBFixedString(1)> Public XJMs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)>
<VBFixedString(2)> Public XJNs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=70)>
<VBFixedString(70)> Public XJOs As Char()
<MarshalAs(UnmanagedType.R4, SizeConst:=4)>
Public XJP As Single
Public XJQ As Single
Public XJR As Single
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
<VBFixedString(1)> Public XJSs As Char()
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=128)>
<VBFixedString(128)> Public XJTs As Char()
End Structure
....
Public SAL555 As SALbchCX
....
Dim f5 As New FileStream(coUC, FileMode.Open, _
FileAccess.ReadWrite, FileShare.ReadWrite, Marshal.SizeOf(SAL555))
For X = 1 To 10
GetBatchRec(X, f5) 'populates SAL555
Next X
....
Public Sub GetBatchRec(RecNumber As Integer, File As FileStream)
Dim b() As Byte
ReDim b(Marshal.SizeOf(SAL555) - 1)
File.Seek((RecNumber - 1) * 600, SeekOrigin.Begin) 'Marshal.Size(SAL555)
File.Read(b, 0, b.Length)
Dim h = GCHandle.Alloc(b, GCHandleType.Pinned)
SAL555 = Marshal.PtrToStructure(Of SALbchCX)(h.AddrOfPinnedObject())
h.Free()
End Sub
我们正在使用ByValArray而不是ByValTStr,因为ByValTStr没有捕获字符串的最后一个字符,因为它期望结束返回char。我们使用SAL5.XJIs =新字符串(SAL555.XJIs)将char()复制到字符串,该字符串再次处理大约2ms的处理。
代码的主要两部分似乎占用了大部分时间。
File.Seek((RecNumber - 1) * 600, SeekOrigin.Begin) 'Marshal.Size(SAL555)
SAL555 = Marshal.PtrToStructure(Of SALbchCX)(h.AddrOfPinnedObject())
每个操作大约需要10毫秒,只需使用fileget()就可以使用大约8毫秒,所以我们在将char()复制到字符串之前就慢了两倍。
我正在跳跃,有人更好地了解如何将数据读取/编组到一个更复杂的结构中。
欢迎任何建议,谢谢Richard
仅供参考:忽略与&#34相关的答案;停止使用平面文件&#34;因为这不是现有选项:)
答案 0 :(得分:0)
经过广泛的性能测试后,我们发现Marshaling的解决方案实际上比vb6 ported fileget()更快。
误导性的事情是,开发环境需要一个时间来运行循环但是当运行编译的EXE或visual studio内置的性能分析器时,编组的性能比fileget()好,我们也没有打过早锁定记录,赢/赢!!
每天学习新东西!
谢谢,理查德。