2011-02-13 81 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() 

試試這個,然後如果不成功發佈異常消息和任何其他信息,你可以。