Can I do this (threading and UI control update)

  • Thread starter Thread starter Just_a_fan
  • Start date Start date
J

Just_a_fan

I want to be able to call my thread safe routine in a more normal way
but I cannot figure out the syntax or even if there is any. I have
tried all variations I can think of.

What I would like to code is:

StatusAdd("Here is the text to display.")

But what I do now is:

Sub Thread2StatusTest()
StatusBoxContents = "Here is the text to display."
StatusAdd()
End Sub

The routine it calls is below. It sees if a delegate invoke is needed
and recalls itself on the control in the main thread. It works just
fine but I would like to be able to call with one statement with a
parameter of what to display rather than the clunky dual statements.

It is the invoke call where the parameter gets lost and I don't know how
to pass it otherwise.

If I put an input parm spec on StatusAdd such as:

Public StatusAdd(sIn as string)

Then I have to put in:

Delegate Sub UIDelegate(ByVal sIn As String)

And then I have a problem with a message saying that the expression does
not produce a value on the following:

lblStatus.Invoke(newDelegate(sIn))

Suggestions?

Mike

---------------------The routine with the delegate invoke---------------

Public Sub StatusAdd()

'This routine HAS to be in the form which owns the control which
will be shared with other threads for reading and writing.
'It CANNOT be in the module file (for some reason I am not sure of
at this time).

Dim lArrayEntries As Integer

If lblStatus.InvokeRequired Then ' If I am on a thread other than
the one which owns the lblStatus control...

'Update the status box by invoking a delegate with the UI control
Dim newDelegate As New UIDelegate(AddressOf StatusAdd) ' Queue up
some work for lblStatus to run StatusAdd
'--or-- Dim newDelegate As UIDelegate = AddressOf StatusAdd

lblStatus.Invoke(newDelegate)
Else

If Strings.Len(Strings.Trim(StatusBoxContents)) = 0 Then Exit Sub
' Don't queue up an empty string.

If lblStatus.Text = "" Then ' First, see if there is any text
in the box.
lblStatus.Text = "(" & Now() & ") " & StatusBoxContents ' If
not, just put this text up for viewing and exit
Exit Sub
Else
lStatusQueue += 1
If Not (lblStatus.Text.EndsWith("(click for more)")) Then
lblStatus.Text &= " (click for more)"
End If
If sStatusQueue Is Nothing Then
lArrayEntries = 0
Else
lArrayEntries = UBound(sStatusQueue)
End If
If lStatusQueue >= lArrayEntries Then ReDim Preserve
sStatusQueue(lStatusQueue)
sStatusQueue(lStatusQueue) = "(" & Now() & ") " &
StatusBoxContents
End If
End If
End Sub
 
I want to be able to call my thread safe routine in a more normal way
but I cannot figure out the syntax or even if there is any. I have
tried all variations I can think of.

What I would like to code is:

StatusAdd("Here is the text to display.")

Took me 15 minutes to understand the problem. :-) Here is the code that
I think that does not work in your project: I put it into a blank
project - and it works! You can call the sub in form_load as you
mentioned. I added 3 fields at the top in order to make it compilable. I
was too lazy to word-wrap the comments, so I omitted them. :) In the
end, I don't see the problem. Maybe I misunderstood.


Delegate Sub UIDelegate(ByVal sIn As String)

Dim lblStatus As Label

Dim lStatusQueue As Integer
Dim sStatusQueue As String()

Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
StatusAdd("bla")
End Sub
Public Sub StatusAdd(ByVal sIn As String)

Dim lArrayEntries As Integer

If lblStatus.InvokeRequired Then ' If I am on a thread
Dim newDelegate As New UIDelegate(AddressOf StatusAdd)

lblStatus.Invoke(newDelegate)
Else

If Strings.Len(Strings.Trim(sIn)) = 0 Then Exit Sub
' Don't queue up an empty string.

If lblStatus.Text = "" Then
lblStatus.Text = "(" & Now() & ") " & sIn
Exit Sub
Else
lStatusQueue += 1
If Not (lblStatus.Text.EndsWith("(click for more)")) Then
lblStatus.Text &= " (click for more)"
End If
If sStatusQueue Is Nothing Then
lArrayEntries = 0
Else
lArrayEntries = UBound(sStatusQueue)
End If
If lStatusQueue >= lArrayEntries Then _
ReDim Preserve sStatusQueue(lStatusQueue)
sStatusQueue(lStatusQueue) = "(" & Now() & ") " & sIn
End If
End If
End Sub


Armin
 
Back
Top