2015-07-20 19 views
0

分支的前一个问题... Retrieving only PRINT command from SQL Server procedure in VB.NET更新文本框关闭SQL InfoMessages导致

我能够从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可以在需要更新时随意调用,还是只针对Event Handler的位置?

Restoration Tool

正如你可以在图片中看到,这是实际的“修复”,该工具通常会报告哪些事务日志已关闭根据收到的SQL消息的恢复,但它仍然是空白期间...

再次谢谢你!

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

+0

听起来你正在进行跨线程GUI更新。尝试在更新'TextBox'时使用'Invoke' - 类似'RestoreTool.txtTRNStatus.Invoke(Sub()RestoreTool.txtTRNStatus.Text =“TRN#”&Counter&“Restored”)' – Mark

回答

1

确保您正确使用backgroundworker。在“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 

有关backgroundworker使用情况的更多详细信息,请参阅MSDN

或者你可以使用像评论中提到的@Mark一样的“invoke”。这告诉主线程执行一个子。只要UI更新是由主线程完成的,你会没事的。