我一直在创建多个后台线程来解析xml文件并重新创建新的xml文件。现在我遇到的问题是即使我在全局变量上使用synclock,我仍然有时会出错并且我确信这只是我正在编写的粗略编码方式,但我想知道是否有人有更好的选项。 程序流程=
我将添加一些代码来显示问题区域,但是如果我使用了已声明的全局变量,那么不同的线程会覆盖变量中的那个值,导致污染。
For Each g In resultsList
gXmlList.Add(g)
Next
Dim bgw As New BackgroundWorker
bgw.WorkerSupportsCancellation = True
AddHandler bgw.DoWork, New DoWorkEventHandler(AddressOf createXML)
AddHandler bgw.RunWorkerCompleted, AddressOf WorkComplete
threadlist.Add(bgw)
bgw.RunWorkerAsync()
Private Sub createXML()
num += 1
Dim file As String = Module1.infile
xmlfile = directoryPath & "\New" & dateTime.Now.ToUniversalTime.ToString("yyyyMMddhhmmss") & endExtension
Thread.Sleep(2000)
Dim doc As XmlDocument = New XmlDocument
**xwriter = New XmlTextWriter(xmlfile, Encoding.UTF8)** this is where ioexception error
xwriter.Formatting = Formatting.Indented
xwriter.Indentation = 2
xwriter.WriteStartDocument(True)
xwriter.WriteStartElement("Posts")
我在应用程序中有全局变量,我是否应该锁定每个变量,这样做不会使用线程然后无用。
Dim j As Integer = 0
答案 0 :(得分:1)
我认为你最大的问题是不知道.Net中的哪些功能是线程安全的。例如,列表不是(字典是)。虽然你可能会逃脱它,但最终会遇到锁定等问题。
您使用非线程安全的类和变量。无论何时使用线程,都必须非常小心锁定。要回答您的问题,是的,您必须锁定并解锁您正在使用的所有内容,除非类型/方法专门为您处理。
.Net 4.0中有很多多线程(例如PLINQ)可以为你处理很多“笨拙的工作”。虽然你应该学习并了解如何自己做线程安全代码,但它会给你一个良好的开端。
尝试将数据传递到createXML()方法。这可能有助于将代码与正在访问的其他数据隔离开来。我建议你阅读线程并学习如何在没有后台工作者的情况下进行操作。
全局变量通常是个坏主意。鉴于你的VB代码,我猜这是一个来自VB6世界的延续。这绝不是为了侮辱,只是试图帮助提升你的技能。可变范围应尽可能限制。
查看代码的另一个想法是学习如何在构建字符串/路径时使用String.Format()。
VB中的简单手动线程可以帮助您入门:
Dim bThread As New Threading.Thread(AddressOf createXML)
bThread.IsBackground = True
bThread.Start()
答案 1 :(得分:1)
如果您遇到线程锁定问题,那么您只需将操作包装在以下庄园中即可。
'This will need to be out of scope so that all threads have access to it
Dim readerWriterLock As New Threading.ReaderWriterLockSlim
readerWriterLock.EnterWriteLock()
xwriter = New XmlTextWriter(xmlfile, Encoding.UTF8)
'other logic
readerWriterLock.ExitWriteLock()
'anything reading from this would need to have the following
readerWriterLock.EnterReadLock()
'logic
readerWriterLock.ExitReadLock()
尝试此操作,如果不成功,请发布异常消息以及您可以使用的任何其他信息。