Solved

Updating TextBox via events. Timing of events. Earlier events run after later events finish.

Posted on 2013-11-19
1
308 Views
Last Modified: 2013-11-20
I have a vb.net windows forms program. The window has a TextBox. Other threads want to update the TextBox. The two types of updates are:

1. Append text to the TextBox
2. Load a file into the TextBox

The threads signal their intention via events:
AddHandler MyClass.AppendTb, AddressOf Me.HandleAppendTb
AddHandler MyClass.TbLoadFile, AddressOf Me.HandleTbLoadFile

Open in new window

(My problem is a timing issue with these events and when they actually get run.)

The handlers use delegates:
Private Delegate Sub TextDelegate(ByVal tf As String)

Open in new window

Each corresponding method tests to see if it's running on the UI thread (.InvokeRequired), if not, it uses a delegate to get the code to run on the UI thread (.Invoke):
Private Sub HandleAppendTb(ByVal sender As Object, ByVal e As StringEventArgs)
    AppendTb(e.txt)   'we are passed the filename in e.txt
End Sub
Private Sub AppendTb(ByVal s As String)    's is the text to append
    If Me.tb.InvokeRequired Then     ' Check if this method is running on a different thread than the thread that created the control.
        Dim d As TextDelegate        ' It's on a different thread, so use Invoke. (We call ourself through a delegate.)
        d = New TextDelegate(AddressOf AppendTb)
        Me.Invoke(d, New Object() {s})
    Else
        Me.tb.AppendText(s)          ' It's on the main UI thread, no need for Invoke
    End If
End Sub

Private Sub HandleTbLoadFile(ByVal sender As Object, ByVal e As StringEventArgs)
    TbLoadFile(e.txt)   'we are passed the filename in e.txt
End Sub
Private Sub TbLoadFile(ByVal f As String)    'f is the filename
    If Me.tb.InvokeRequired Then    ' Check if this method is running on a different thread than the thread that created the control.
        Dim d As TextDelegate       ' It's on a different thread, so use Invoke. (We call ourself through a delegate.)
        d = New TextDelegate(AddressOf TbLoadFile)
        Me.Invoke(d, New Object() {f})
    Else
        Me.TbDoLoadFile(f)          ' It's on the main UI thread, no need for Invoke
    End If
End Sub
'Executes on UI Thread
Private Sub TbDoLoadFile(ByVal f As String)
    Dim myFile As New FileInfo(f)
    Dim sizeInBytes As Long = myFile.Length
    If sizeInBytes = 0 Then
        Me.tb.AppendText("<no results to display>")
    Else
        Me.tb.Text = File.ReadAllText(f)
    End If
End Sub

Open in new window

The main code does this:
Loop
    Append Text to TextBox
End Loop
Read File into TextBox

Open in new window

It appends numerous lines to the TextBox, then eventually switches to loading a file into the TextBox. But it actually does this all via sending events, so it really does this:
Loop
    Raise event to Append Text to TextBox
End Loop
Raise event to Read File into TextBox

Open in new window

The problem now is the code will Read File into TextBox, followed later by some leftover event that attempts to Append Text to TextBox, and that attempt gets very unhappy, complaining that the TextBox has already been disposed.

(Actually I'm not sure if that's what is happening. I just know I'm getting "Can not access disposed object TextBox" errors.)

Should I just throw in some Try...Catch statements in my AppendTb and TbLoadFile which give up if there are any errors? Or is there something more fundamental about what's happening that a better fix might cure?

Should I use .BeginInvoke instead?
0
Comment
Question by:deleyd
1 Comment
 
LVL 30

Accepted Solution

by:
Alexandre Simões earned 500 total points
ID: 39661853
Well although it's a bit difficult for me to understand what's going on, updating UI from other threads have always been unsafe.

Wouldn't it be better for those threads to update a kind of log file and add a FileWatcher to the Windows Forms application that updates the textbox whenever the file changes?
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Need to grow your business through quality cloud solutions? With everything required to build a cloud platform and solution, you may feel like the distance between you and the cloud is quite long. Help is here. Spend some time learning about the Con…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

914 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now