High frequency event handling in VB.NET

I'm working with a market data feed API in VB.NET.  API is written is written in C#.

This API calls a method in one of my classes to signal when an event such as a price tick or a trade arrives on a TCP socket.  This can happen upwards of 10,000 times per second.  After the event comes in, the data is converted from a byte stream into data structures and the data structures are used in a pricing model.

Each event can take a couple ms to process, so multi-threading is probably necessary.  If events are not processed in time, they queue up, but this is extremely undesirable, so we want to process events without them backing up.

I wanted to gather your thoughts on the do's and don't of processing this many events.  For example, should I use the ThreadPool.QueueWorkItem or should I build my own threadpool?

Has anyone used ThreadPool.QueueWorkItem for so many small work items?

If I build my own threadpool, the approach that makes sense is to create a wrapper for the thread, and suspend the thread.  When an event arrives, put the data into the wrapper and call resume() to make the thread process the event.  Once the processing is complete, do another suspend() because once a thread dies, it cannot be restarted.

If I build my own threadpool, what is the overhead of doing suspend/resume so frequently?  What have been your experiences with having many threads going on and off at the same time?

Thanks in advance
sevzasAsked:
Who is Participating?
 
vigylantCommented:
Suspend/Resume is deprecated. If you want your thread to wait, try using Threading.EventWaitHandle or something similar.

If you keep the thread running all the time (Which is the whole point of using EventWaitHandle), there is very little overhead, probably not noticeable.

As a queue, you could simply use System.Collections.Queue.
At my Q6600 CPU, it could dequeue about 10 million items in 120ms, which apparently is more than you need, so it should work.

In this code, they will however queue up, and you mentioned this was undesireable, so i dont know if this code is goign to help you, but here goes :)

Make one class of this, and use Add(obj) to enqueue an item.
Public Class TCPQueue
 
    Dim WH As New Threading.EventWaitHandle(False, Threading.EventResetMode.ManualReset)
    Dim Q As New System.Collections.Queue
 
    Public Sub New()
 
        Dim T As New Threading.Thread(AddressOf Worker)
        T.Start()
 
    End Sub
 
    Public Sub Add(ByVal obj As Object)
 
        Queue.Synchronized(Q).Enqueue(obj)
        WH.Set()
 
    End Sub
 
    Private Sub Worker()
 
        Do
 
            Do While Queue.Synchronized(Q).Count > 0
 
                Dim obj As Object = Queue.Synchronized(Q).Dequeue
                'Process here
 
            Loop
 
            WH.WaitOne()
            WH.Reset()
 
        Loop
 
    End Sub
 
End Class

Open in new window

0
 
sevzasAuthor Commented:
vigylant: Thanks for the code.  It's nice that you showed me how to use a waithandle.  This is a very helpful class.

I can probably deploy an array of these queues to process the events.

I'm still curious whether it would be just as effective to throw all of these events into the ThreadGroup that the CLR makes available to me.  Does anyone have experience with ThreadGroup ?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.