Trouble Calling Events From Threads

G

Guest

I am having trouble getting events fired from threads to call back on the
original thread. I have an non-UI "sub" assembly that periodically goes out
and retrieves information. When it finds new or changed information it fires
events to whoever is listening (could be another sub-assembly or a WinForm
application). I am currently using the code I pieced together below to fire
the events:

Public Shared Sub Fire(ByVal del As [Delegate], ByVal ParamArray args() As
Object)
Dim temp As [Delegate] = del

If temp Is Nothing Then
Return
End If
Dim delegates As [Delegate]() = temp.GetInvocationList()
For Each sink As [Delegate] In delegates
Try
Dim invokeChecker As System.ComponentModel.ISynchronizeInvoke =
sink.Target
If invokeChecker.InvokeRequired Then
invokeChecker.BeginInvoke(sink, args)
Else
sink.DynamicInvoke(args)
End If
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
Next sink
End Sub

The problem with this code is the "Dim invokeChecker" line fails if the
event was not created by a WinForm. I can't seem to find a way to invoke an
event on a non-UI thread (which most of the threads in my applications are).
If I just put "sink.DynamicInvoke(args)" in the Catch, then when I am using a
UI, the UI always tells me that Invoke is required when it gets the event.

I thought maybe implementing ISynchronizeInvoke in my classes that have
events might work, but I can't find any sample code on what to do in the
methods, especially InvokeRequired.

Any help would be greatly appreciated!
David McCarter
 
W

Wiktor Zychla

I am having trouble getting events fired from threads to call back on the
original thread. I have an non-UI "sub" assembly that periodically goes
out
and retrieves information. When it finds new or changed information it
fires
events to whoever is listening (could be another sub-assembly or a WinForm
application). I am currently using the code I pieced together below to
fire
the events:

Public Shared Sub Fire(ByVal del As [Delegate], ByVal ParamArray args() As
Object)
Dim temp As [Delegate] = del

If temp Is Nothing Then
Return
End If
Dim delegates As [Delegate]() = temp.GetInvocationList()
For Each sink As [Delegate] In delegates
Try
Dim invokeChecker As System.ComponentModel.ISynchronizeInvoke =
sink.Target
If invokeChecker.InvokeRequired Then
invokeChecker.BeginInvoke(sink, args)
Else
sink.DynamicInvoke(args)
End If
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
Next sink
End Sub

The problem with this code is the "Dim invokeChecker" line fails if the
event was not created by a WinForm. I can't seem to find a way to invoke
an
event on a non-UI thread (which most of the threads in my applications
are).
If I just put "sink.DynamicInvoke(args)" in the Catch, then when I am
using a
UI, the UI always tells me that Invoke is required when it gets the event.

I thought maybe implementing ISynchronizeInvoke in my classes that have
events might work, but I can't find any sample code on what to do in the
methods, especially InvokeRequired.

Any help would be greatly appreciated!
David McCarter

did you try to invoke delegates on UI-thread with Invoke method of the Form?
consult

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp

for more details.

Wiktor Zychla
 
G

Guest

The article you mentioned assumes you have a form to call Invoke on (unless I
am missing something). I can't assume that the caller of my assembly is a
form (even though I have to account for this). In the end, I want to fire my
events back to the calling assembly on the same thread that they created the
event on.

David

Wiktor Zychla said:
I am having trouble getting events fired from threads to call back on the
original thread. I have an non-UI "sub" assembly that periodically goes
out
and retrieves information. When it finds new or changed information it
fires
events to whoever is listening (could be another sub-assembly or a WinForm
application). I am currently using the code I pieced together below to
fire
the events:

Public Shared Sub Fire(ByVal del As [Delegate], ByVal ParamArray args() As
Object)
Dim temp As [Delegate] = del

If temp Is Nothing Then
Return
End If
Dim delegates As [Delegate]() = temp.GetInvocationList()
For Each sink As [Delegate] In delegates
Try
Dim invokeChecker As System.ComponentModel.ISynchronizeInvoke =
sink.Target
If invokeChecker.InvokeRequired Then
invokeChecker.BeginInvoke(sink, args)
Else
sink.DynamicInvoke(args)
End If
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
Next sink
End Sub

The problem with this code is the "Dim invokeChecker" line fails if the
event was not created by a WinForm. I can't seem to find a way to invoke
an
event on a non-UI thread (which most of the threads in my applications
are).
If I just put "sink.DynamicInvoke(args)" in the Catch, then when I am
using a
UI, the UI always tells me that Invoke is required when it gets the event.

I thought maybe implementing ISynchronizeInvoke in my classes that have
events might work, but I can't find any sample code on what to do in the
methods, especially InvokeRequired.

Any help would be greatly appreciated!
David McCarter

did you try to invoke delegates on UI-thread with Invoke method of the Form?
consult

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp

for more details.

Wiktor Zychla
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top