I learned a couple of things about WaitHandles this morning (8/14/2005) that I didn't know before:
- WaitHandle.WaitAll doesn't work on STAThreads.
- WaitHandle.WaitAll and WaitHandle.WaitAny are limited to 64 handles.
I found this out in the context of some testing. I wanted to write a class to encapsulate piping data from one stream to the next using the asynchronous read/write methods on stream. I added a ManualResetEvent to the class so that I could tell when the process was complete. After getting it to work for one, I kicked up about 100 of them and then called WaitAll to see what would happen.
First, I got the STAThread-related exception. This one was interesting to me, because I was running my test via TestDriven.Net's "test with debugger." Normally, I love "test with debugger." Oh well.
So, I create a console driver app, newed up a Test instance, SetUp, Test method, Wham! 64 handle limit. OK, so a little arithmetic can help out with that.
Then I set the number of pipes to 1000. The test read the file into a memory stream, converted to a string, and compared to a string obtained by reading the file via StreamReader.ReadToEnd(). It blew up with an OutOfMemoryException. It wasn't obvious to me why that was true at the time, but CLR Profiler impressed upon me the reason. I had been increasing the size of the file to try to get the system to require more threads, but I wasn't having much luck, so I made the file bigger until I noticed a non-negligible difference in the amount of time the program actually ran.
The test file that I was reading in was ~3MB.
3MB *1000 = 3GB. D'oh.
How could I overcome this??? Another way would be to throttle the number of concurrent pipes. One way would be to meter my usage of internal memory buffers, i.e. create a pooled set of byte buffers. Finally, I could make a test stream that verifies the values byte-by-byte, in hopes of minimizing the memory consumption. This would be closer to the usage model that I intend, at least initially. Haven't gotten there yet, but I will do that next. I will probably end up with a solution that uses a combination of all three approaches, or at least the last two.
Sidebar: What happens when you enter http://testdriven.net into your browser? 400 - Bad Request. It is 2005. I shouldn't have to type "www," should I? I need to create a hall of shame web page of site that require www. Of course, int TD.NET's case, I love the ide integration so much that I am willing to dismiss both the STA and www issues as nuetron-sized nits.
Recent Comments