VB.Net Winform Application based on BackgroundWorker Thread concept - UI update issue

和自甴很熟 提交于 2019-12-11 10:49:50

问题


Team,
I have build a VB.Net windows application which does uploads data into database and basically updates two controls:
1. A textbox which is constantly updated with one line per database record upload.
2. A label which keeps track of the count of database record uploaded.

I have used BackgroundWorker thread concept, where the thread's bgwWorker_DoWork() method contains the business logic for upload and bgwWorker_ProgressChanged() updates the 2 UI controls based on uploads.

But the issue I am facing is that I do not get complete updates on both the UI controls. Sometimes the thread bypasses update of textbox and sometimes of label. I could resolve this issue by adding System.Threading.Thread.Sleep(25) before each UI control update code. Is this correct way of solving the issue? OR is there something I am missing?

Kindly suggest.

Below is the code in both these methods:

Private Sub bgwWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwWorker.DoWork
    .................
    .................
    'Updates database record related update in textbox
    System.Threading.Thread.Sleep(25)
    updater.eventName = "UpdateStatusBox"
    updater.errorMessageToLog = String.Empty
    updater.errorMessageToLog += GetErrorMessage(dataTable(rowNumber)("Name").ToString(), ExceptionData)
    bgwWorker.ReportProgress(1, updater)

    .................
    .................
    'Updates Status Count in LABEL  
    System.Threading.Thread.Sleep(25)
    updater.eventName = "UpdateStatusBar"
        updater.successCount = successCount.ToString()
        updater.failureCount = failureCount.ToString()
        bgwWorker.ReportProgress(2, updater)
End Sub

Private Sub bgwWorker_ProgressChanged(ByVal sender As System.Object, ByVal e As ProgressChangedEventArgs) Handles bgwWorker.ProgressChanged
        Dim updater As UIUpdater = TryCast(e.UserState, UIUpdater)

    ..........................................
        If updater.eventName = "UpdateStatusBar" Then
            UpdateStatusBar(updater.successCount, updater.failureCount)
        ElseIf updater.eventName = "UpdateStatusBox" Then
            txtUpdates.Text = txtUpdates.Text & updater.errorMessageToLog
        End If
        .....................................
End Sub

回答1:


I'm almost positive that your problem is your instance of the UIUpdater object called updater. This object appears to be declared globally and is thus shared between calls.

Omitting a little bit of code this is what you have:

updater.eventName = "UpdateStatusBox"
bgwWorker.ReportProgress(1, updater)

updater.eventName = "UpdateStatusBar"
bgwWorker.ReportProgress(2, updater)

Although you call ReportProgress() linearly, it doesn't fire your ProgressChanged event immediately nor does it block until that method completed. To do so would defeat the purpose of threading if you think about it.

To put it another way, you have a global object that you are setting a property on. You then say "when someone gets a chance, do something with this". You then change a property on that global object and sometimes this happens before "someone has done something" happens.

The solution is either to create two global variables, one for each possible event or to just create an instance variable when needed. I'm not sure that its thread safe to use a global variable the way you are so I would recommend just creating an instance variable. In fact, the state object you pass to ReportProgress could just be a string.




回答2:


I would NOT use a sleep in your DoWork event.

Have you tried refreshing the control after you update it? Each control has a Refresh method which forces a redraw. This may result in flickering though.

Another option is to include the information needed for both controls (textbox and label) in a single call to ReportProgress rather than trying to make two calls.



来源:https://stackoverflow.com/questions/9019475/vb-net-winform-application-based-on-backgroundworker-thread-concept-ui-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!