Solved

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

Posted on 2013-11-19
1
312 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

Guide to Performance: Optimization & Monitoring

Nowadays, monitoring is a mixture of tools, systems, and codes—making it a very complex process. And with this complexity, comes variables for failure. Get DZone’s new Guide to Performance to learn how to proactively find these variables and solve them before a disruption occurs.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
How to repeat the data 4 30
How to force output to ascii 2 37
VB.net/VSTO Excel Add-in 2 16
Nested forach loop to linq 3 27
In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

749 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