分离上一个问题... Retrieving only PRINT command from SQL Server procedure in VB.NET
我能够从SQL Server的消息中转储所有文本并使用我需要的但由于某种原因我无法使用事件更新我的文本框。
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已恢复”)
我也在使用后台工作程序来调用实际执行数据库还原的过程。该过程包含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,还是只针对事件处理程序的位置?
正如您在图像中看到的那样,在实际的“恢复”期间,该工具通常会根据收到的SQL消息报告已恢复的事务日志,但它仍为空白...
再次感谢你!
编辑:我的后台工作者的进度更新设置正确,我只是在调用来自OnInfoMessage Sub的事件作为进度更新时遇到问题,这是从SQL获取下一行的地方。答案 0 :(得分:1)
确保正确使用背景工作者。在“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一样使用“调用”。这告诉主线程执行一个sub。只要UI更新由主线程完成,您就可以了。