3

私はバックグラウンド ワーカー コントロールを初めて使用します。ファイルをビルドする既存のプロジェクトがありますが、ファイルのビルド中にプロジェクト全体でデッドロック エラーが発生します。バックグラウンドワーカーのみで構成される別のプロジェクトを作成して解決しようとしています。次に、それらをマージします。

私の問題は、バックグラウンド ワーカーを実装するのがより効果的な場所がわからないことです。また、主な問題は、バックグラウンド ワーカーで 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
4

1 に答える 1

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()は停止モードに設定しておけば、到達すると再び停止します。

このコードは 2 つの を定義しますManualResetEvents。をクリックすると、新しいでButton1関数が開始され、次に が開始されます。関数は を表示してで待機するので、関数を使用するとファイル ダイアログが表示されます。FileOpener()ThreadBackgroundWorkerFileOpener()FileOpenDialoglocker1locker1.Set()

myOpenFile「グローバル」変数 (およびbOpenFileOK) であるため、ユーザーがファイルを選択すると (または選択されない場合)、ダイアログの結果 ( bOpenFileOK) と選択されたファイルを検出できます。

于 2013-01-14T09:05:17.700 に答える