2011-02-13 34 views
1

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

  • 访问本地文件夹,并上传所有文件到列表
  • 条每个文件转换成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 
+1

不是你问题的原因,但不要使用`New XmlTextWriter`。改为使用`XmlWriter.Create`。从.NET 2.0开始,新的XmlTextWriter已被弃用。 – 2011-02-13 00:26:42

回答

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() 
+0

非常有帮助谢谢 – vbNewbie 2011-02-13 01:34:36

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

试试这个,然后如果不成功发布异常消息和任何其他信息,你可以。