473,750 Members | 2,292 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

ThreadPool VS Thread

Hi. I'm writing a Client/Multi-threaded Server program on Windows
Vista. It worked fine on Windows Vista, but when the server ran on
Windows XP,

I/O operation has been aborted because of either a thread exit or an
application request

exception randomly occurred at the OnReceive method (asynchronous tcp
stream reading). I searched all over the internet and found a post
posted few years ago. He had the same problem as me, and he said it
seemed like a bug of the .NET framework. He said changing normal
Thread to ThreadPool solved the problem but he couldn't explain the
reason. So I tried his explanation and it really solved the problem
(as least till now)

My original code was:
Dim client As TcpClient = Listener.Accept TcpClient()
Dim t As New Thread(New ParameterizedTh readStart(Addre ssOf
OnNewClient))
t.Start(client)

And I rewrote like:
Dim client As TcpClient = Listener.Accept TcpClient()
ThreadPool.Queu eUserWorkItem(N ew WaitCallback(Ad dressOf OnNewClient),
client)

Could you please tell me what was wrong with my original code? And
using ThreadPool really solves the problem? I mean can there be any
other possiblilities of new problem?

Thank you as always.
--------------------------------------------------
PS, other parts of the code are
Private Sub OnNewClient(ByV al client As Object)
Interlocked.Inc rement(LastID)
If LastID = Integer.MaxValu e Then
LastID = Integer.MinValu e
End If
Dim c As TcpClient = CType(client, TcpClient)
Dim handler As New ClientHandler(c , LastID)
Clients.Add(han dler)
AddHandler handler.Message Received, AddressOf OnMessageReceiv ed
AddHandler handler.Connect ionClosed, AddressOf OnConnectionClo sed
End Sub

Public Class ClientHandler
Public Sub New(ByVal client As TcpClient, ByVal id As Integer)
TheClient = client
_ClientID = id
ClientStream = client.GetStrea m()
Dim state As New StateObject()
state.WorkSocke t = client.Client
client.Client.B eginReceive(sta te.RawBuffer, 0,
StateObject.Buf ferSize, SocketFlags.Non e, New AsyncCallback(A ddressOf
OnReceive), state)
End Sub

Feb 27 '07 #1
7 5900
On 27 Feb 2007 03:54:30 -0800, Sin Jeong-hun wrote:
I/O operation has been aborted because of either a thread exit or an
application request

exception randomly occurred at the OnReceive method (asynchronous tcp
stream reading). I searched all over the internet and found a post
posted few years ago. He had the same problem as me, and he said it
seemed like a bug of the .NET framework. He said changing normal
Thread to ThreadPool solved the problem but he couldn't explain the
reason. So I tried his explanation and it really solved the problem
(as least till now)
I've been bitten by this exact same problem a few days ago. Blame the
really poor documentation of the Socket classes. The problem is that "All
I/O initiated by a given thread is canceled when that thread exits. A
pending asynchronous operation can fail if the thread exits before the
operation completes." (taken from MSDN).

The thing is that this comment has only been added in the documentation of
..NET 2 but wasn't there as far as i can see in the doc of .NET 1 even
though .NET 1 suffers from the same problem.

So if you initate an asynchonous I/O operation in a thread (which is what
you do when you call BeginReceive in your ClientHandler class), this
operation will be canceled if this thread exits leading to the exception
you get in the callback method.

In your case, you manually create a thread, then in this thread you create
an instance of ClientHandler which calls BeginReceive after which your
thread has nothing to do anymore and therefore dies, canceling in the
process your asynchronous operation.

The solution is to always initate asynchronous I/O calls (that is call the
BeginXXX methods of I/O classes) from a thread that never dies (for the
duration of your application) or that you know won't die before the
operation has completed. Typically this would be either:

- the main UI thread in the case of a UI application
- a thread from the threadpool since these threads are always kept alive to
be re-used by the .NET runtime
- a thread from a custom thread pool that you know are kept alive for the
duration of your application
- an IOCP thread, which are the threads in which callbacks of asyncronous
I/O operations are executed. I can't say for sure that they are always kept
alive but so far i haven't had problems initiating async I/O operations
from an IOCP thread. It seems logical to be able to iniate a new async I/O
operation from the callback method of the previous one.

So your solution of using the threadpool works. Just beware of not
executing any long running code in a threadpool thread as they are in
limited numbers (25 / processor) and are used by the .NET framework
internally. Alternatively, if you've got a main thread in your application
that never dies, switch to using async I/O excusively so that you're always
working in IOCP threads.
Feb 27 '07 #2
On Feb 27, 11:52 pm, Mehdi <vio...@REMOVEM E.gmail.comwrot e:
On 27 Feb 2007 03:54:30 -0800, Sin Jeong-hun wrote:
I/O operation has been aborted because of either a thread exit or an
application request
exception randomly occurred at the OnReceive method (asynchronous tcp
stream reading). I searched all over the internet and found a post
posted few years ago. He had the same problem as me, and he said it
seemed like a bug of the .NET framework. He said changing normal
Thread to ThreadPool solved the problem but he couldn't explain the
reason. So I tried his explanation and it really solved the problem
(as least till now)

I've been bitten by this exact same problem a few days ago. Blame the
really poor documentation of the Socket classes. The problem is that "All
I/O initiated by a given thread is canceled when that thread exits. A
pending asynchronous operation can fail if the thread exits before the
operation completes." (taken from MSDN).

The thing is that this comment has only been added in the documentation of
.NET 2 but wasn't there as far as i can see in the doc of .NET 1 even
though .NET 1 suffers from the same problem.

So if you initate an asynchonous I/O operation in a thread (which is what
you do when you call BeginReceive in your ClientHandler class), this
operation will be canceled if this thread exits leading to the exception
you get in the callback method.

In your case, you manually create a thread, then in this thread you create
an instance of ClientHandler which calls BeginReceive after which your
thread has nothing to do anymore and therefore dies, canceling in the
process your asynchronous operation.

The solution is to always initate asynchronous I/O calls (that is call the
BeginXXX methods of I/O classes) from a thread that never dies (for the
duration of your application) or that you know won't die before the
operation has completed. Typically this would be either:

- the main UI thread in the case of a UI application
- a thread from the threadpool since these threads are always kept alive to
be re-used by the .NET runtime
- a thread from a custom thread pool that you know are kept alive for the
duration of your application
- an IOCP thread, which are the threads in which callbacks of asyncronous
I/O operations are executed. I can't say for sure that they are always kept
alive but so far i haven't had problems initiating async I/O operations
from an IOCP thread. It seems logical to be able to iniate a new async I/O
operation from the callback method of the previous one.

So your solution of using the threadpool works. Just beware of not
executing any long running code in a threadpool thread as they are in
limited numbers (25 / processor) and are used by the .NET framework
internally. Alternatively, if you've got a main thread in your application
that never dies, switch to using async I/O excusively so that you're always
working in IOCP threads.
Thank you so much. I didn't expect that I would get such a detailed
reply.
My server probably has to handle 50~100 clients at the same time
(max).
So if using ThreadPool can only create 25 threads, that could be a
problem.

You said that I have to initiate asynchronous reading in a thread that
never dies.
As you see my code, it's a multi-threaded server. If I initiate
reading clients' messages
other than the ClientHandler thread, how can I tell which client from
the other clients?

I'm sorry for my ignorance but I can't get the picture. Currently,
each ClientHandler
thread serves one client. If reading is initiated in other thread, how
can I keep the
ClientHandler running and make the ClientHandler process the client's
incoming data?

Was my approach for Multi-threaded server wrong at the first place? I
wonder if you
could tell me how to design the workflow of a multi-threaded server
that could handle
about 100 clients at most.

Thank you.

Feb 27 '07 #3
You said that I have to initiate asynchronous reading in a thread that
never dies.
As you see my code, it's a multi-threaded server. If I initiate
reading clients' messages
other than the ClientHandler thread, how can I tell which client from
the other clients?
Each delegate comes with a "this" pointer, so make the event handler a
method inside the class containing per-client data, then all member
variables will be accessible to the handler code as it runs.
>
I'm sorry for my ignorance but I can't get the picture. Currently,
each ClientHandler
thread serves one client. If reading is initiated in other thread, how
can I keep the
ClientHandler running and make the ClientHandler process the client's
incoming data?
Each client needs its own data structure, but not its own thread. There's
no reason to have one thread per client, in fact it's bad (per queueing
theory, the average response time is considerably lower with a single
high-rate processor, than many slow processors running in parallel, which is
what threading emulates).
>
Was my approach for Multi-threaded server wrong at the first place? I
wonder if you
could tell me how to design the workflow of a multi-threaded server
that could handle
about 100 clients at most.
Best performance is gotten with only one thread per processor. When you
receive a message, process it by sending the next outgoing message and
return to waiting for the next message. Note that messages in this case
aren't just client requests, typically a client request might trigger a
query to the database, <here you must return to the main listen loopthe
database's reply triggers the response message back to the client.

Only if you have to use a poorly designed library such as a blocking
database API, so you need extra threads to just sit and wait for that
operation to complete. With pure message passing, your thread never waits
as long as there is work to do for any client.

This architecture is sometimes called a state machine (by hardware engineers
like me), continuations (by computer sci folks familiar with Lisp and
Scheme), completion callbacks (by OS engineers), etc. Just some terms to
google for.

Ultimately, this is the same as the difference between sequential
command-line interfaces vs an event-driven GUI. And just as in that case,
you have to stop thinking in terms of "X must happen next" and start
thinking of "if data Y arrives, it enables me to finish preparing Z"
Feb 27 '07 #4
| - a thread from the threadpool since these threads are always kept alive
to
| be re-used by the .NET runtime

Threads from thread pool and iocp pool can and do get collected after some
lag timeout if they are not used. So not sure this is safe either.

| - an IOCP thread, which are the threads in which callbacks of asyncronous
| I/O operations are executed. I can't say for sure that they are always
kept
| alive but so far i haven't had problems initiating async I/O operations
| from an IOCP thread. It seems logical to be able to iniate a new async I/O
| operation from the callback method of the previous one.

This seems to work and many code I see does this (and I have done it).
However, I also wonder if this is just a bug waiting to happen. Is it just
the fact we are getting lucky and the iocp thead is always keep alive during
our usage (as we normally get a reply pretty fast under normal conditions)?
Or does the os do some fixup behind the covers that allows the async call to
remain thread agnostic because we started it on an IOCP thread? I would
love to know the answer.

| So your solution of using the threadpool works. Just beware of not
| executing any long running code in a threadpool thread as they are in
| limited numbers (25 / processor) and are used by the .NET framework
| internally.

..Net 2.0 added api to set min and max threads on both the thread pool and
iocp pool.

| Alternatively, if you've got a main thread in your application
| that never dies, switch to using async I/O excusively so that you're
always
| working in IOCP threads.

Again back to second issue of calling Beginxxx on a iocp thread. It seems
to work fine, but wonder if we can force a failure. Will have to test this
sometime.
--wjs
Feb 28 '07 #5
On Wed, 28 Feb 2007 01:32:56 -0500, William Stacey [C# MVP] wrote:
This seems to work and many code I see does this (and I have done it).
However, I also wonder if this is just a bug waiting to happen. Is it just
the fact we are getting lucky and the iocp thead is always keep alive during
our usage (as we normally get a reply pretty fast under normal conditions)?
Or does the os do some fixup behind the covers that allows the async call to
remain thread agnostic because we started it on an IOCP thread? I would
love to know the answer.
I've done quite a lot of reading over the last few days regarding this
issue and it seems that nobody really knows the answer to that. There is an
awful lot of confusion when it comes to async socket operations. Everybody
seems to aggree that async socket calls should be prefered over sync calls
for scalabilty reasons but nobody seems to know how to actually use async
socket calls. And the documentation doesn't help either. I find this quite
astonishing as socket programming is as the heart of many applications
nowdays, not really a very specific, niche programming technique. How come
Microsoft doesn't come up with a white paper about these issues? For now,
i'll keep doing what everybody else does and hope for the best but i don't
feel particularly good about it either.
Feb 28 '07 #6

| I've done quite a lot of reading over the last few days regarding this
| issue and it seems that nobody really knows the answer to that. There is
an
| awful lot of confusion when it comes to async socket operations. Everybody
| seems to aggree that async socket calls should be prefered over sync calls
| for scalabilty reasons but nobody seems to know how to actually use async
| socket calls. And the documentation doesn't help either. I find this quite
| astonishing as socket programming is as the heart of many applications
| nowdays, not really a very specific, niche programming technique. How come
| Microsoft doesn't come up with a white paper about these issues? For now,
| i'll keep doing what everybody else does and hope for the best but i don't
| feel particularly good about it either.

I agree. If it works as documented, there is a lot of broken async socket
code out there - they just don't know it.
--wjs
Feb 28 '07 #7
I agree. This has me pretty worried, at some level.

On the other than, emperical evidence says things work pretty well, and
there's probably nothing to worry about. We've got thousands of hours
hammering on our stuff, and it's pretty darn reliable...

--
Chris Mullins, MCSD.NET, MCPD:Enterprise , Microsoft C# MVP
http://www.coversant.com/blogs/cmullins

"William Stacey [C# MVP]" <wi************ @gmail.comwrote in message
news:eP******** ******@TK2MSFTN GP04.phx.gbl...
>
| I've done quite a lot of reading over the last few days regarding this
| issue and it seems that nobody really knows the answer to that. There is
an
| awful lot of confusion when it comes to async socket operations.
Everybody
| seems to aggree that async socket calls should be prefered over sync
calls
| for scalabilty reasons but nobody seems to know how to actually use
async
| socket calls. And the documentation doesn't help either. I find this
quite
| astonishing as socket programming is as the heart of many applications
| nowdays, not really a very specific, niche programming technique. How
come
| Microsoft doesn't come up with a white paper about these issues? For
now,
| i'll keep doing what everybody else does and hope for the best but i
don't
| feel particularly good about it either.

I agree. If it works as documented, there is a lot of broken async socket
code out there - they just don't know it.
--wjs


Feb 28 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
1677
by: David Levine | last post by:
Jon, I've taken a look at it and these comments are based on a code-inspection but I did not verify the correctness if its operation by using it in a sample. The ctor for CustomThreadPool increments instanceCount before the lock(staticLock)...why not inside of the lock? The MinThreads and MaxThread properties do not validate the values...I
8
4808
by: memememe | last post by:
We are queueing stuff on the thread pool and what we are queueing gets done pretty quick (the method returns fine) but yet its only allowed to run around 25 times, is there anything I need to do to tell the threadpool that my method is done running and the thread is to be disposed of?
5
2759
by: Duane Pressley | last post by:
I'm looking for someone to help me make sense of the results I'm observing when using the ThreadPool class in a COM-Interop scenario. Here's the set up: 1.. A classic ASP page instantiates and calls MethodA on COM+ Class (C1). 2.. MethodA of COM+ class (C1) instantiates and calls MethodB of .NET class (N1). (Note: N1 has been registered using RegASM and is present in the GAC). 3.. MethodB of .NET class (N1) uses the...
6
2755
by: Max Adams | last post by:
Threads and ThreadPool's If I use a ThreadPool how can I tell when a thead in the threadpool has exited? I don't want to set a global member variable I would much rather be able to act on an event Also (failing this ThreadPool issue) is it possible to create an array of Worker Threads, can anyone illustrate with code please Thanks
10
8776
by: Lenn | last post by:
Hello, I have always used a certain design pattern for multithreaded Windows app; Start new worker thread from UI thread, use events to notify UI threads when something happens, update UI controls using delegates through .BeginInvoke. I came across some code samples recently where ThreadPool class is used to start new threads. My questions; 1. what's the difference? 2. Any performance benefits?
3
2495
by: UltimateBanoffee | last post by:
Hi, I'm using asp.net 2.0 and I have an understanding issue here! I don't quite understand when the available threads in the ThreadPool are ever used. The application I have running doesn't use ThreadPool.QueueWorkItem, and doesn't create any other Threads. So say I have 100 users access my application at the exact same time and they all call on an aspx that takes a couple of seconds to process. I gather 100 sessions are active, but...
6
1631
by: Ricardo Vazquez | last post by:
Hello everybody, I'm programming a TCP server. During the stress tests I noticed that maybe my socket-receiving thread became deaf after an hour of heavy stress. I think that the reason could be this: The processing of the received messages. Something goes wrong in this processing and the code gets stuck here. As the processing is within the receiving "while" loop, the loop gets also stuck, so that we will never reach again the...
7
1636
by: Curious | last post by:
On Jun 10, 3:32 am, <s...@dailycoding.comwrote: Thanks! I'll use thread pool.
7
7201
by: =?Utf-8?B?cmJEZXZlbG9wZXI=?= | last post by:
The following is from a simple Windows application in VS2005, which has button1 and textbox1 dragged onto a form. In StartThreads(), I call ThreadPool.QueueUserWorkItem(), then call WaitOne(). My expectation is that I would see the text generated in WasteTime() before seeing the "Hey" printout that comes after WaitOne(). Instead, I'm seeing the "Hey" as the first thing to print out in the text box. Any thoughts on why WaitOne() isn't...
0
8999
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8836
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9256
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6803
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6080
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4712
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4885
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3322
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 we have to send another system
3
2223
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.