Solved

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

Posted on 2013-11-19
1
314 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
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…
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…

630 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