Thursday, April 21, 2005


We had a mid-month North Dallas .NET User Group meeting tonight. David Chappell came and talked to us about Indigo, Microsoft's next framework for distributed computing, combining their web services, remoting, and enterprise services stuff into one big framework, all built on top of .net 2.0, itself to be released later this year. Thoughts:

1. Microsoft sometimes comes out with super cool stuff. This looks like this will be one of those things. And I can't wait till .net 2.0 comes out this Fall either...
2. I am reminded what a great industry the software industry is to work in. With such interesting technology, who wouldn't want to do this?
3. I like free pizza, and they give us some at the meetings.
4. We had drawings and I was only two numbers off from getting a copy of Visual Studio. Of course, I already have one. But it never hurts to have extras.

Service Oriented Architecture. I really think there is something to that in a lot of situations. And that, basically, was what the talk was about, at least implementing it in Indigo.

Now the only truly thought-shifting thing that happened during the meeting happened when we talked about the idea of separating the service interface from the class hierarchy that will undergird it. He showed a code sample, with a private method in a class that was meant to be invoked during the service call. Of course, at first this just seemed backwards. Private methods are meant to be called outside of the class at all, yet here we are exposing them over web services.

Then he explained it. And it really clicked and made sense to me. In the object-oriented world, the idea of having a private method callable in such a way is truly abhorrent, and that is accurate. It is. But this is different. We're talking about the creation of the external service interface.

So here is the rational. If you make the web service methods private yet accessible via webservices, you have a way of enforcing within your class a way to keep the business logic from calling that web service method. The service method exists to be called from the outside, not generally from the inside. That's why you attach the service attribute and make it callable from the outside, but make it private and not callable outside the class within the code.

Here's an example. Let's say you have an application for getting book information. The data is stored in some RDMS. At least in my applications, book objects that are created to represent the book entities in the db will usually be identified by some primary key id, usually an identity/auto-incremented column. That's what is its main identifier. So if you have a class that is called "BookManager" that has a GetBook() method, chances are you'll have something like this:

public Book GetBook( int bookID )

But, if you want something callable over a webservice, that won't work. They don't know what's in your db, much less your primary key id's. You might make a method for them that looks like this:

public Book GetBook( string isbn )

Assuming you aren't going to use the second method within your library, you can mark that method private and give it the service attribute:

private Book GetBook( string isbn )

With this you keep a method from being called from within the library that is not meant to be called, but at the same time expose it to the world. I like the idea.

Great meeting!


Some anonymous commenter left a link to Slashdot. As any of you who read the biblioblogs probably know, some news has been announced recently about researchers having the ability to read some of the papyri at Oxyrhynchus that they could not read before. That is very cool. I hope this will be very fruitful.

If you haven't been there, the Oxyrhynchus online website is very cool. The interface they have now is much better than the old one, so be thankful. Of course, their online images, though nice, are not as nice at the ones at (shameless plug).

Fishing Stories

I caught a fish that was thiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis long.

But I'll get to that. All in all I had a really good time. Despite the first night. For some reason I was thinking "cabin", but what we had was not nearly that nice. We had a big cement slab with screened in walls. So, the floor wasn't very comfortable. But that wasn't the real problem. All I brought was a blanket and a sheet, and it was about 50 degrees that night. I froze, because I used the blanket for padding and the sheet for covers. Of course, the sheet I grabbed randomly out of the closet was one of those fitted sheets with the elastic around the edges, so I would wake up freezing throughout the night and find the sheet curled up around my feet. Way too cold. The next night we went to Super WalMart and I got a sleeping bag. MUCH better.

The fishing was not very...productive. Very few caught more than a fish or two. I caught one, about a three-pounder, so I was pleased with that.

Most of the time, however, was spent sitting around and talking theology. That was fun. Night time theology talk. Theology in the morning. Theology during the day. Lots of fun and fellowship, and good food. I really don't like fishing a whole lot anyway, so this was definitely the best way to spend my time.

But, back to the daily grind.

Friday, April 15, 2005

Gone Fishing

On a men's retreat this weekend. I expect to be reading, fishing, talking, reading, or sleeping for the next two days. Can't beat that.

Wednesday, April 13, 2005

New Interpreters Dictionary of the Bible

Well, since others such as Jim and Jim are mentioning their contributions to the NIDB, I figured I would also share what I'm contracted to write:

Mandrake Soup (Recipe)

This last entry should be particularly interesting. The editors chose me because of my ground-breaking theories on the subject. I have argued offline for years that the story of the flood has been changed over time to hide the fact that the God flooded the world for the sake of Noah, because everyone was beginning to join circuses and Noah had a very severe case of coulrophobia. It hasn't made it into the scholarly journals yet, but give it time. I've also thought of making the idea widespread by appealing to a mass audience through fictional novel writing. After all, if LaHaye and Jenkins can popularize a worse chunk of theology that way, why can't I?

Tuesday, April 12, 2005

Threads Gone Wild

See! It's not just me! The Mono wiki has a page now relating to my last post. Of course, it has been there for about two weeks now. But I just noticed it since I'm so behind on my blog reading :(

Monday, April 11, 2005

HttpWebRequest class and Threads in .NET

So I was messing around with something this weekend and found something rather annoying about a particular bit of functionality in the .NET framework. This is incredibly rare, actually, so I thought I would blog about it. I was doing two things: multi-threaded coding using the System.Threading.ThreadPool and the System.Net.HttpWebRequest class.

Using the ThreadPool is really easy to do. Using the HttpWebRequest class is easy to do. Getting them to play nicely together takes some work. Take this syntax for example:

ThreadPool.QueueUserWorkItem( new WaitCallback(someMethod) );

That's all it takes to add some work item to the thread pool. Easy enough. I never thought multi-threaded programming could be so easy! This method, however, used an object which used the HttpWebRequest class. In my testing in the beginning I was queuing maybe 10 items at a time. All the while everything worked very well. I was happy. The program was happy. No exceptions for thread issues were being thrown. Woohoo!

Then I started queuing 100 items at a time. CRASH! It started throwing expections, saying that there were not enough free threads in the thread pool. Of course, I'm thinking "But the ThreadPool class is supposed to handle this for me!" After some looking I found the problem, and I'm not the first to experience this.

The HttpWebRequest class also spawns its own threads, and it doesn't really communicate with the ThreadPool. So if the ThreadPool gets to its max limit of threads, and then the HttpWebRequest class instances start spawning their own threads, the runtime is going to start throwing exceptions. You can only have so many threads per processor, you know! Not cool! You see the problem?

So, how do you handle this? I heard of one way and thought of another, and ended up going with the latter. I saw it recommended somewhere to handle my own thread pooling. That makes sense, I suppose. But that's not what I did. So the problem, we see, is related to how many items we put in the ThreadPool at one time, right? Yes. So, you can also solve this problem by limiting that number. In my case, I did this by having a class that tracked the state of my work items. I had a timer that looked at my various collections and checked how many items were in the threadpool at the moment.

First, it would take the amount set by me as the max amount and put those in the ThreadPool.
Second, every second my timer would check back and see how many items had been completed. If, say, 3 had been completed, that means that I had three free threads, so I would add three more. Etc.
Third, when the number of completed items equaled the number of total items, I knew I was finished. At that point I knew to update my UI to show that I was done.

Make sense? If anyone else found a different way to handle this, I'm interested in hearing about it.

I found a knowledge base article thingy on msdn about the topic (can't remember the url right off the top of my head). It says that this interaction between the ThreadPool and the HttpWebRequest class was actually by design. Why, I haven't figured out. It is incredibly rare for me to find something about the behavior of the .NET framework that I don't really like. This is one of those times. But, I survived.

Update to CSNTM

I think the most important thing that I failed to blog about recently was an update to We now have digitial photographs of 11 complete manuscripts up on the site. So, if you dig Greek, digital photography, and old manuscripts, you just really have no choice but to check out what is there :)

Of course, Stephen Carlson has already pointed this out a while back, so this may not be news to many of you. Thanks, Stephen.

The Coding Humanist - Back In Action!

These last few weeks have been absolutely horrific in terms of free time. Work has absolutely kept me swamped. But, things are calming down. Finally. So, I'm back. And hopefully back to answering email more quickly :)