2013-01-14 146 views
3

我是非常新的後臺工作人員控制。我有一個現有的項目,建立文件,但在我的項目中,同時構建文件,我得到了死鎖錯誤。 我想通過創建另一個只包含背景工作者的項目來解決它。然後我會合並它們。後臺工作人員和SaveDialog

我的問題是我不知道它將對我的後臺工作人員更有效,並且主要問題是如何將SaveDialog與我的後臺工作人員一起使用?我需要發送一個參數給我的後臺工作人員項目,告訴它什麼時候我的文件正在生成。

這是我的文件將被編譯:

srOutputFile = New System.IO.StreamWriter(strFile, False) 'Create File 

    For iSeqNo = 0 To iPrintSeqNo 
    ' Loop through al the record types 
    For Each oRecord As stFileRecord In pFileFormat 
     If dsFile.Tables.Contains(oRecord.strRecordName) Then 
     ' Loop through al the records 
     For Each row As DataRow In dsFile.Tables(oRecord.strRecordName).Rows 
      ' Check record id 
      If oRecord.strRecordId.Length = 0 Then 
      bMatched = True 
      Else 
      bMatched = (CInt(oRecord.strRecordId) = CInt(row.Item(1))) 
      End If 

      ' Match records 
      If iSeqNo = CInt(row.Item(0)) And bMatched Then 
      strRecord = "" 
      ' Loop through al the fields 
      For iLoop = 0 To UBound(oRecord.stField) 
       ' Format field 
       If oRecord.stField(iLoop).iFieldLength = -1 Then 
       If strRecord.Length = 0 Then 
        strTmp = row.Item(iLoop + 1).ToString 
       Else 
        strTmp = strDelimiter & row.Item(iLoop + 1).ToString 
       End If 
       ElseIf oRecord.stField(iLoop).eFieldType = enumFieldType.TYPE_VALUE Or _ 
        oRecord.stField(iLoop).eFieldType = enumFieldType.TYPE_AMOUNT_CENT Then 

       strTmp = row.Item(iLoop + 1).ToString.Replace(".", "").PadLeft(oRecord.stField(iLoop).iFieldLength, "0") 
       strTmp = strTmp.Substring(strTmp.Length - oRecord.stField(iLoop).iFieldLength) 
       Else 
       strTmp = row.Item(iLoop + 1).ToString.PadRight(oRecord.stField(iLoop).iFieldLength, " ").Substring(0, oRecord.stField(iLoop).iFieldLength) 
       End If 

       If oRecord.stField(iLoop).iFieldLength > -1 And (bForceDelimiter) And strRecord.Length > 0 Then 
       strTmp = strDelimiter & strTmp 
       End If 

       strRecord = strRecord & strTmp 
      Next 

      ' Final delimiter 
      If (bForceDelimiter) Then 
       strRecord = strRecord & strDelimiter 
      End If 

      srOutputFile.WriteLine(strRecord) 
      End If 
     Next 
     End If 
    Next 
    Next 

回答

1

你可以試試這個:

Private locker1 As ManualResetEvent = New System.Threading.ManualResetEvent(False) 
Private locker2 As ManualResetEvent = New System.Threading.ManualResetEvent(False) 
Dim bOpenFileOK As Boolean 
Dim myOpenFile As OpenFileDialog = New OpenFileDialog() 

Private Sub FileOpener() 
    While Not bTerminado 
     If myOpenFile.ShowDialog() = System.Windows.Forms.DialogResult.OK Then 
      bOpenFileOK = True 
     Else 
      bOpenFileOK = False 
     End If 

     locker2.Set() 
     locker1.WaitOne() 
    End While 
End Sub 

' Detonator of the action 
Private Sub Button1_Click(ByVal sender As System.Object, _ 
ByVal e As System.EventArgs) Handles Button1.Click 
    Dim tFileOp As Thread = New Thread(AddressOf FileOpener) 
    tFileOp.SetApartmentState(ApartmentState.STA) 
    tFileOp.Start() 

    ' Start BackgroundWorker 
    BW1.RunWorkerAsync() 
End Sub 

Private Sub AsyncFunctionForBW(ByVal args As ArrayList) 
    '[...] 

    'Change options dinamically for the OpenFileDialog 
    myOpenFile.Filter = "" 
    myOpenFile.MultiSelect = True 

    'Calling the FileDialog 
    locker1.Set() 
    locker2.WaitOne() 
    locker1.Reset() 
    locker2.Reset() 

    If bOpenFileOK Then 
     myStream = myOpenFile.OpenFile() 

     '[...] 
    End If 
End Sub 

這是一個有點複雜,但它的工作原理。

ManualResetEvents當到達使用.Set()時,中斷代碼的執行(如果它們被告知停止)。如果使用.WaitOne(),則將其設置爲停止模式,以便在到達時再次停止。

此代碼定義了兩個ManualResetEvents。當您單擊Button1啓動功能FileOpener()中新的Thread,然後啓動BackgroundWorkerFileOpener()函數顯示FileOpenDialog並在locker1中等待,所以當您使用locker1.Set()時,該函數顯示文件對話框。

由於myOpenFile是一個「全局」變量(以及bOpenFileOK),一旦用戶選擇文件(或不選擇),您可以檢測到對話結果(bOpenFileOK)和所選文件。

+0

感謝您的快速響應。你可能只是簡單地解釋一下你在做什麼,因爲我是新的線程和後臺工作者,我想完全理解你在做什麼。 – Gericke

+0

@ G-Man當然。我正在編輯我的答案,並提供更多評論來清除代碼正在做什麼。 – SysDragon

+0

@ G-Man完成。如果你什麼都不明白就問。對不起,如果我的解釋不清楚。 – SysDragon