正在根据 SQL InfoMessages 结果更新文本框

Updating Textbox based off SQL InfoMessages results

从上一个问题分支...

我能够从 SQL 服务器的消息中转储所有文本并使用我需要的内容,但由于某种原因我无法使用事件更新我的文本框。

    Private Shared Sub OnInfoMessage(ByVal sender As Object, ByVal e As System.Data.SqlClient.SqlInfoMessageEventArgs)


    Dim Counter As Integer

    Counter = 1

    For Each line In e.Message.Split(vbNewLine)

        If (line.Contains("====")) Then

            RestoreTool.txtTRNStatus.Text = "TRN #" & Counter & "Restored"

            Using LogFile As IO.StreamWriter = New IO.StreamWriter("C:\SDBT\worklog.ft", True)

                LogFile.WriteLine(line)

            End Using


            Counter += 1

        End If
    Next

一切运行顺利,但文本框 (txtTRNStatus) 没有更新任何内容并保持空白(应该显示的地方 "TRN #1 Restored")

我也在使用后台工作者来调用实际执行数据库恢复的过程。该过程包含 SQLInfoMessages 的事件处理程序。

 Dim SQL As SqlCommand
    Dim DBConn As New SqlConnection(ConnectionString)

    SQL = New SqlCommand(DBScript, DBConn)

    AddHandler DBConn.InfoMessage, New SqlInfoMessageEventHandler(AddressOf OnInfoMessage)

 Dim SQLResult As IAsyncResult = SQL.BeginExecuteNonQuery()


    Try

    Catch e As Exception

        MessageBox.Show(e.Message)

    End Try

    SQL.EndExecuteNonQuery(SQLResult)



    CompletedTask = True


    DBConn.Close()

我觉得让文本更新的唯一方法是通过在 Backgroundworker 的 DoWork() 部分添加一些东西,但无法弄清楚到底是什么。 OnInfoMessages 是否可以在需要更新时随意调用,还是仅特定于事件处理程序所在的位置?

正如您在图片中看到的,在实际 "restoration" 期间,该工具通常会根据收到的 SQL 消息报告已恢复哪个事务日志,但它仍然是空白的。 ..

再次感谢您!

编辑:我的后台工作人员的进度更新设置正确,我只是无法从 OnInfoMessage Sub 调用事件作为进度更新,这是从 SQL 获取下一行的地方。

确保正确使用后台程序。在 "doWork" 中不得有任何影响 UI(UserInterface) 的代码行,因为此线程不是应用程序的主线程。如果是这样,它要么崩溃,要么什么都不做。

因此,如果您需要从后台工作者更改 UI,您将需要通过 "DoWork" 方法告诉主线程这样做。这可以通过将回调挂接到 backgroundWorker 对象的事件 "ProgressChanged" 来实现。

 ' This event handler updates the UI. '
Private Sub backgroundWorker1_ProgressChanged( _
ByVal sender As Object, ByVal e As ProgressChangedEventArgs) _
Handles backgroundWorker1.ProgressChanged

    Me.txtTRNStatus.Text = e.UserState.ToString()//Update UI

End Sub 

从 "DoWork" 方法中,引发如下所示的事件以告知主线程更新 UI。使用第二个参数传递主线程所需的任何内容。

Private Sub backgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs)
   ' This method will run on a thread other than the UI thread. '
   ' Be sure not to manipulate any Windows Forms controls created' 
   ' on the UI thread from this method.'

   Dim SomeObject As [Object]
   //some stuff
   backgroundWorker.ReportProgress(1, SomeObject)
   //some stuff
   backgroundWorker.ReportProgress(2, SomeObject)

 End Sub

有关后台工作程序使用的更多详细信息,请参阅 MSDN

或者您可以像@Mark 在评论中建议的那样使用 "invoke"。这告诉主线程执行一个子线程。只要 UI 更新由主线程完成就可以了。