473,503 Members | 1,747 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

vb 2005, .net 2.0 - ? how to make a cross-thread call, independent of GUI ?

MTEXX
5 New Member
Hi all-

I'm trying to wrap the Socket class to raise events on the same thread that the class is instantiated on. For example: connected(), stateChanged(), dataArrival() etc- similar to old vb6 Winsock. The class interface should not block. Eg subs and events. Likewise, the events should fire back on the same thread that created the class. This must work for a Windows Service as well.

It's easy to spawn a new thread. But when something interesting happens in there, how do I make a call on another thread?

Is there something I could do such as mOriginalThread.invoke(onDataArrival) ?

Thanks in advance
Jan 9 '08 #1
2 2511
MTEXX
5 New Member
Well, I'll answer my own question. Or at least post a workaround.

Purpose:
Use asynchronous methods, whose callbacks are on unknown threads, to raise events on a known thread.
ALSO must NOT utilize Windows.Forms such that this can be used in a Windows Service (though it may be possible...)

Method:
I will use a queue to store information about events to raise. Appending and reading from the queue shall all be thread safe.

Example:
I will demonstrate wrapping the System.Net.Socket class to appear similar to VB6's Winsock object.

Partial Sample Code:
* I'm not going to post an entire class, but I'll give the essentials.
1) In the "Winsock" class, we'll need to make a private enum to describe the style of event.
Expand|Select|Wrap|Line Numbers
  1. Private Enum EventStyles
  2.     stateChanged
  3.     sendProgress
  4.     dataArrival
  5.     newConnection
  6. End Enum
2) Now make a struct to contain the least common multiple of all event data.
Expand|Select|Wrap|Line Numbers
  1. Private Structure EventData
  2.     Dim style As EventStyles
  3.     Dim prev As States
  4.     Dim curr As States
  5.     Dim bytesSent As Integer
  6.     Dim data As String
  7.     Dim peer As Winsock
  8. End Structure
3) Define your events as public:
Expand|Select|Wrap|Line Numbers
  1. Public Event stateChanged(ByVal sender As Winsock, ByVal prevState As States, ByVal newState As States)
  2. Public Event sendProgress(ByVal sender As Winsock, ByVal bytesSent As Integer)
  3. Public Event dataArrival(ByVal sender As Winsock, ByVal data As String)
  4. Public Event newConnection(ByVal sender As Winsock, ByVal peer As Winsock)

4) Make a Queue for storing your EventData instances
Expand|Select|Wrap|Line Numbers
  1. Private mEventQueue As Queue 'System.Collections i think...
5) Instantiate the queue in New()
Expand|Select|Wrap|Line Numbers
  1. mEventQueue = new Queue
6) Where you would usually do a RaiseEvent, instead, populate a EventData struct and enqueue it using a helper method. You will see that I also lock when modifying the queue.
Expand|Select|Wrap|Line Numbers
  1. Private Sub enqueueStateChanged(ByVal prev As States, ByVal curr As States)
  2.     Dim ed As EventData
  3.     ed.style = EventStyles.stateChanged
  4.     ed.bytesSent = 0
  5.     ed.curr = curr
  6.     ed.data = ""
  7.     ed.peer = Nothing
  8.     ed.prev = prev
  9.     enqueueEvent(ed)
  10. End Sub
  11.  
  12. Private Sub enqueueEvent(ByVal ed As EventData)
  13.     Monitor.Enter(Me)
  14.     mEventQueue.Enqueue(ed)
  15.     Monitor.Exit(Me)
  16. End Sub
7) For the user to retrieve the event on a known thread, he must execute code on a known thread. I have not found a way to do this otherwise. Notice above that in order to keep the thread locked as short as possible, I make a copy of the queue, THEN consume the copy.
Expand|Select|Wrap|Line Numbers
  1. Public Sub doEvents()
  2.     Dim myQueue As Queue = New Queue
  3.  
  4.     Monitor.Enter(Me)
  5.     If (mEventQueue.Count > 0) Then
  6.         myQueue.Enqueue(mEventQueue.Dequeue)
  7.     End If
  8.     Monitor.Exit(Me)
  9.  
  10.     If (myQueue.Count > 0) Then
  11.         Dim ed As EventData
  12.         ed = myQueue.Dequeue
  13.         Select Case ed.style
  14.             Case EventStyles.dataArrival
  15.                 RaiseEvent dataArrival(Me, ed.data)
  16.             Case EventStyles.newConnection
  17.                 RaiseEvent newConnection(Me, ed.peer)
  18.             Case EventStyles.sendProgress
  19.                 RaiseEvent sendProgress(Me, ed.bytesSent)
  20.             Case EventStyles.stateChanged
  21.                 RaiseEvent stateChanged(Me, ed.prev, ed.curr)
  22.         End Select
  23.     End If
  24. End Sub
* Form code
8) In a form, for example, here is how I use the Winsock class. Define the reference using "WithEvents" as usual.
Expand|Select|Wrap|Line Numbers
  1. Private WithEvents sckClient As Winsock
9) Inside FormLoad or whatnot:
Expand|Select|Wrap|Line Numbers
  1. sckClient = New Winsock
  2. tmrDoEvents.Start() 'A WinForms Timer - set to 1 millisecond
10) Make the timer call the Winsock's DoEvents (as described above)
Private Sub tmrDoEvents_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrDoEvents.Tick
sckClient.doEvents()
End Sub

'Here you see that consuming an event WILL occur on the proper thread- in this case the GUI thread, which is where tmrDoEvents_Tick() occurs:
Expand|Select|Wrap|Line Numbers
  1. Private Sub sckClient_stateChanged(ByVal sender As xxxxx.Winsock, ByVal prevState As xxxxxx.Winsock.States, ByVal newState As xxxxxx.Winsock.States) Handles sckClient.stateChanged
  2.     'Console.WriteLine("frmWinsock::sckClient_stateChanged() thread id " & System.Threading.Thread.CurrentThread.ManagedThreadId.ToString)
  3.     sckImgClient.setState(sender.state)
  4.     If (sender.state = Winsock.States.error_) Then
  5.         Console.WriteLine("frmClient::sckClient_StateChanged: " + sender.errorMessage)
  6.     End If
  7. End Sub


I hate doing lengthy workarounds, especially when they involve risk and time. But this demonstrates at least that the workaround does indeed work.
Cheers,
-MTEXX
Feb 4 '08 #2
Plater
7,872 Recognized Expert Expert
I am not sure you are using events in the manor that they were designed for.
I am also curious as to why you were going back to the archaic winsock style, just for familiarity sake?
Feb 4 '08 #3

Sign in to post your reply or Sign up for a free account.

Similar topics

0
2103
by: Unigroup of New York | last post by:
Content-Type: multipart/mixed; boundary="------------C465DF38DCB38DD2AF7117E0" Lines: 327 Date: Tue, 15 Feb 2005 23:36:38 -0500 NNTP-Posting-Host: 24.46.113.251 X-Complaints-To: abuse@cv.net...
0
1712
by: Rare Book School | last post by:
RARE BOOK SCHOOL 2005 Rare Book School is pleased to announce its schedule of courses for 2005, including sessions at the University of Virginia, the Walters Art Museum/Johns Hopkins University...
0
1561
by: melledge | last post by:
Full Programme for XTech 2005 Announced Premier European XML Industry Event Expands Focus to "XML, the Web and Beyond"; Co-hosted by the Mozilla Foundation,W3C, and OASIS, Presenters Include...
0
1884
by: melledge | last post by:
IDEAlliance's XTech 2005 to Cover Hot Trends in Browser Technology As Mozilla, Google, Flickr, Microsoft and Others Redefine Web Interfaces, Conference Will Feature Insights and Perspective from...
6
1145
by: Paul Aspinall | last post by:
Hi I have VS 2005, but some of the components I'm using (Infragistics NetAdvantage 2005), have issues with .NET 2.0 For this reason, I'm being forced to compile against .NET 1.1 How do I do...
3
2080
by: jason | last post by:
I've been working with C# for over a year now without touching vb.net code. I had a few light years of vb.net before that. No real vb6 or windows form experience. Suddenly, I have an assignment...
1
3632
by: Iwan Petrow | last post by:
Hi, I do this - take some data with sqldataadaptor (at this moment 2000rows) in fill datatable. For each two rows do some calculations and save data to the database with insert command. (the...
1
11632
by: Alex | last post by:
Hi Everyone, Most of our MS SQL Servers are still running on SQL 2000, but being I will soon be upgrading my workstation to Vista Business I'd like to install MS SQL 2005 Enterprise Manager to...
1
2088
by: tomzji | last post by:
I am using Sql server 2005. I have one table named 'tblJob'. This table have two fields say 'Staus' and 'ExpiryDate'. when 'Expirydate' come to less than current date, i want to upadte 'Status'...
7
1678
by: puzzlecracker | last post by:
Is there way to format all my source file in project, perhaps follow some generic template (then I would also need one) since i have a lot of files and I don't want to screw it up manually? ...
0
7203
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7087
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7334
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7462
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
4675
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3168
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3156
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1514
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
737
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.