T
taskswap
I have a legacy application written in C that I'm trying to convert to
C#. It processes a very large amount of data from many clients
(actually, upstream servers - this is a mux) simultaneously.
I've read through what must be dozens of ways to do socket
communication in C#, and it seems they all devolve into three basic
options - Socket.Select, IOCP through a native interface, and
Asynchronous callbacks. I'm fine using Asynchronous callbacks, which
all the documentation and articles I've read seem to indicate is the
most scalable solution. My concern is over the ThreadPool involved.
I might have 40-60 connections talking simultaneously, and during peak
periods that can be 150+. Note that this ran fine without threads by
handling the data in round-robin fashion, so it can handle blocking if
that's what will happen when the thread pool gets starved. What it
can't tolerate is ADDITIONAL performance degradation. That is, if
hitting that magic 25-thread limit is going to make things not just N
ticks slower, but N^2 ticks slower as the system struggles to do some
thread magic I don't know about, then I'll have issues.
So, some questions:
What, exactly, will happen when I starve the ThreadPool?
Is there a list somewhere of other I/O (like file) activity I'll affect
by doing this?
If I have a dual-proc + HT box, 4 virtual processors, does this mean MY
application gets 100 theoretical asynch threads to use (25 per
processor)? Scalability via CPU is just fine with me.
Will I affect other applications running on the box (is the ThreadPool
shared across all of .Net, or just my application?)
Should I be trying to write a custom ThreadPool? If so, are there any
pointers on how to tell socket asynchronous functions to use the custom
pool? Or do I just make real threads and use blocking I/O?
Is there housekeeping overhead while the sockets are asleep? (If I have
3000 clients connected but very few talking, is that a problem?)
Do I really need a StateObject class? I have a wrapper class that does
all the dirty work described above. Any reason I can't just keep the
byte[] buffer and other elements in the wrapper and use "this" when I
call BeginReceive?
Any reason I can't just reference my instance variables without even
bothering with the StateObject indirection? I was going to instantiate
a new wrapper for every connection.
Thanks,
Chad
C#. It processes a very large amount of data from many clients
(actually, upstream servers - this is a mux) simultaneously.
I've read through what must be dozens of ways to do socket
communication in C#, and it seems they all devolve into three basic
options - Socket.Select, IOCP through a native interface, and
Asynchronous callbacks. I'm fine using Asynchronous callbacks, which
all the documentation and articles I've read seem to indicate is the
most scalable solution. My concern is over the ThreadPool involved.
I might have 40-60 connections talking simultaneously, and during peak
periods that can be 150+. Note that this ran fine without threads by
handling the data in round-robin fashion, so it can handle blocking if
that's what will happen when the thread pool gets starved. What it
can't tolerate is ADDITIONAL performance degradation. That is, if
hitting that magic 25-thread limit is going to make things not just N
ticks slower, but N^2 ticks slower as the system struggles to do some
thread magic I don't know about, then I'll have issues.
So, some questions:
What, exactly, will happen when I starve the ThreadPool?
Is there a list somewhere of other I/O (like file) activity I'll affect
by doing this?
If I have a dual-proc + HT box, 4 virtual processors, does this mean MY
application gets 100 theoretical asynch threads to use (25 per
processor)? Scalability via CPU is just fine with me.
Will I affect other applications running on the box (is the ThreadPool
shared across all of .Net, or just my application?)
Should I be trying to write a custom ThreadPool? If so, are there any
pointers on how to tell socket asynchronous functions to use the custom
pool? Or do I just make real threads and use blocking I/O?
Is there housekeeping overhead while the sockets are asleep? (If I have
3000 clients connected but very few talking, is that a problem?)
Do I really need a StateObject class? I have a wrapper class that does
all the dirty work described above. Any reason I can't just keep the
byte[] buffer and other elements in the wrapper and use "this" when I
call BeginReceive?
Any reason I can't just reference my instance variables without even
bothering with the StateObject indirection? I was going to instantiate
a new wrapper for every connection.
Thanks,
Chad