Solved

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

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

Enroll in May's Course of the Month

May’s Course of the Month is now available! Experts Exchange’s Premium Members and Team Accounts have access to a complimentary course each month as part of their membership—an extra way to increase training and boost professional development.

Question has a verified solution.

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

Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

751 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