线程尚未掌握..仍然存在ioexception错误

时间:2011-02-13 00:01:24

标签: vb.net multithreading visual-studio-2008

我一直在创建多个后台线程来解析xml文件并重新创建新的xml文件。现在我遇到的问题是即使我在全局变量上使用synclock,我仍然有时会出错并且我确信这只是我正在编写的粗略编码方式,但我想知道是否有人有更好的选项。 程序流程=

  • 访问本地文件夹并将所有文件上传到列表中
  • 将每个文件删除为xml条目,并将这些条目放入arraylist
  • 解析特定值并将这些值输入数据库表
  • 现在创建一个线程并获取条目的arraylist,线程将重新分析
  • 线程解析并创建一个新的xml文件
  • 主线程继续使用另一个函数,然后从列表中获取文件

我将添加一些代码来显示问题区域,但是如果我使用了已声明的全局变量,那么不同的线程会覆盖变量中的那个值,导致污染。

    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

2 个答案:

答案 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()

尝试此操作,如果不成功,请发布异常消息以及您可以使用的任何其他信息。