Just a small .Net thing that's kinda cool.
Lots of people write messages to the console of console apps by using Console.Write()/WriteLine()
If you're really working in a console app, that's great. Of course, the problem is that a lot of these console apps get converted to services or windows apps or web pages or whatever. Console.Write() in an aspx page will actually work and not throw an error, but it adds no value.
Even if you're really working in a true console app, the messages you write often scroll by and get lost.
So lots of people write messages to log files. Typically, someone will creat a "Log" class with a "WriteLog" method or something. I've done this, and it's handy. At one point what was cool is that my Logger class was just a wrapper to Log4Net, so I was able to trap the exceptions, put them into the database and into a local text file at the same time (in case the database was down). I even had a method to accept Exceptions and write them out. Cool stuff.
But what if you're working with old code filled with Console.Write() and you want to avoid a global replace? Or what if you've got developers working with you and just can't break them of the habit of Console.Write()?
I ran across this solution and thought it was worth a post.
The Console.Write uses a Console.Out object under it to actually do the write. Console.Out is just a TextWriter. And it can be overridden. (Don't you *love* OO?) So you can say:
FileStream fs = new FileStream("Test.txt", FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
Console.SetOut(sw);
From that point on, anything that runs within the scope of this will write Console information to the "Test.txt" file. For example, if you do it in the Main of your program, anything in the application will write it's console messages to this file.
I love that. I think it's handy and cool. How do you set it back?
Before you change it, you need to store the old value of Console.Out somewhere, then just re-SetOut() it back to what it was, and all new Console messages go to the Console. So you can have the Main() write a couple things to the Console (starting messsages, etc), then have everything else write to the text file. Then, re-set back to the console to put out the ending messages.
The really cool thing is that the writer doesn't need to be a system object. As long as it implements the same interface as TextWriter, the Console class doesn't care. So I could , for example, take my Logger class and make it implement the TextWriter API, then pass that into the SetOut() and all the console messages would get logged through Log4Net wherever I wanted them. Note that TextWriter is an abstract class, so it's all set up to subclass and override.
Very cool stuff... enjoy,
--kevin
Wednesday, April 13, 2011
Friday, March 25, 2011
IPV4
I mentioned this a while ago that I saw a black market opportunity for IPV4 addresses. Microsoft is one of the first to jump into the pool, it seems:
http://www.pcmag.com/article2/0,2817,2382616,00.asp
MS picks up 666,000 (ominous number, no?) IP addresses from Nortel. I’d expect this to continue. Look for big companies to buy other companies just to get their IP addresses.
In the long term, they’ll likely switch to IPV6, but it’s much cheaper to buy a range of IPV4’s in the short term than it is to upgrade every piece of computer hardware in the company.
Just thought it was interesting enough to post.
--kevin
http://www.pcmag.com/article2/0,2817,2382616,00.asp
MS picks up 666,000 (ominous number, no?) IP addresses from Nortel. I’d expect this to continue. Look for big companies to buy other companies just to get their IP addresses.
In the long term, they’ll likely switch to IPV6, but it’s much cheaper to buy a range of IPV4’s in the short term than it is to upgrade every piece of computer hardware in the company.
Just thought it was interesting enough to post.
--kevin
Tuesday, February 8, 2011
Excel Perspective revisited
Last week, I was asked to do something really simple. Most of my team was out of town and I was on “hold down the fort” duty. So my boss’ boss comes over with an emergency that needs immediate attention. Seems there’s a report that produces a spreadsheet that lists users who have done something bad, but doesn’t add any contact information. It needs two more columns so that the users’ bosses can actually call and yell at them.
So far, so good. Two more columns to a spreadsheet sounds easy enough. It takes me a while to actually find out how the report is generated, but I do.
Problem1: the report is basically a DTS package – not SSIS or anything else supported in the last 30 years – but an old version of Microsoft DTS that hasn’t been supported since the Lincoln administration. I’ve no clue how to work with the thing or how to even open it.
I button hole one poor, unfortunate comrade who got stuck in Ohio with me and he is almost as clueless as I, but suggests that maybe we can convert the package to SSIS so that we can manipulated it. I spend the rest of the day trying.
After a few hours smashing my head on my desk as hard as I can, I realize that the issue I’m having is that
Problem 2: the DTS package itself is corrupt, so it won’t port. I pull the DTS package from production and not only find out that the development version is corrupt, but that the development version is wrong. The flows are almost entirely different, and it’s pretty obvious that the dev version is way out of synch.
Armed with the “correct” version, I end up deciding not to upgrade to SSIS, since… hey.. I can actually open this package.
Problem 3: The package isn’t launched from Sql Server. It’s launched from this in-house scheduling tool that someone wrote in the late 90’s (in Power Builder, I think, if that tells you anything). And it’s all kicked off by a batch file… yes… a .bat… a 300-line .bat file.
I figure out the data relationships and modify the queries in the DTS and push to our dev server only to find out that the thing won’t run. Not only that, but I’m not getting any error trapping from the actual DTS – that is, the bat file is swallowing them.
I spend another couple hours trying to get the batch file to correctly report the errors when I noticed
Problem4: The batch file on dev is out of synch with the one in production. I pull down the prod one, add some error handling and (*ding*) now it runs and I have a valid error message logged.
Problem 5: I spend another hour tracking down the error message only to realize that the DTS package modification I did, didn’t “take” – meaning there were 4 queries and 3 of them saved when I pressed “save”, but the other didn’t. There was, after all, a reason that Microsoft decommissioned DTS.
Problem 6: once I got all this resolved, I was so excited that everything actually worked that I … well.. didn’t noticed that I’d actually messed up the query. It’s partly because I’d misunderstood the data relationships. It’s partly because I didn’t account for one of the error conditions. But it’s mostly because I was so distracted by the stupid plumbing that I’d missed the fact that water was coming through the roof.
I guess part of my point is to rant. But mostly it’s to point out how simple things can drive you nuts. From my boss’ boss’ perspective, it’s just two more columns to a spreadsheet –what can be so hard about that? In fact, I thought the same thing when I looked at it.
Gets back to the “Excel Perspective” that I’ve blogged about before. If you can do it in excel, why does it take 4 months to do it on a server?
This is why.
--kevin
So far, so good. Two more columns to a spreadsheet sounds easy enough. It takes me a while to actually find out how the report is generated, but I do.
Problem1: the report is basically a DTS package – not SSIS or anything else supported in the last 30 years – but an old version of Microsoft DTS that hasn’t been supported since the Lincoln administration. I’ve no clue how to work with the thing or how to even open it.
I button hole one poor, unfortunate comrade who got stuck in Ohio with me and he is almost as clueless as I, but suggests that maybe we can convert the package to SSIS so that we can manipulated it. I spend the rest of the day trying.
After a few hours smashing my head on my desk as hard as I can, I realize that the issue I’m having is that
Problem 2: the DTS package itself is corrupt, so it won’t port. I pull the DTS package from production and not only find out that the development version is corrupt, but that the development version is wrong. The flows are almost entirely different, and it’s pretty obvious that the dev version is way out of synch.
Armed with the “correct” version, I end up deciding not to upgrade to SSIS, since… hey.. I can actually open this package.
Problem 3: The package isn’t launched from Sql Server. It’s launched from this in-house scheduling tool that someone wrote in the late 90’s (in Power Builder, I think, if that tells you anything). And it’s all kicked off by a batch file… yes… a .bat… a 300-line .bat file.
I figure out the data relationships and modify the queries in the DTS and push to our dev server only to find out that the thing won’t run. Not only that, but I’m not getting any error trapping from the actual DTS – that is, the bat file is swallowing them.
I spend another couple hours trying to get the batch file to correctly report the errors when I noticed
Problem4: The batch file on dev is out of synch with the one in production. I pull down the prod one, add some error handling and (*ding*) now it runs and I have a valid error message logged.
Problem 5: I spend another hour tracking down the error message only to realize that the DTS package modification I did, didn’t “take” – meaning there were 4 queries and 3 of them saved when I pressed “save”, but the other didn’t. There was, after all, a reason that Microsoft decommissioned DTS.
Problem 6: once I got all this resolved, I was so excited that everything actually worked that I … well.. didn’t noticed that I’d actually messed up the query. It’s partly because I’d misunderstood the data relationships. It’s partly because I didn’t account for one of the error conditions. But it’s mostly because I was so distracted by the stupid plumbing that I’d missed the fact that water was coming through the roof.
I guess part of my point is to rant. But mostly it’s to point out how simple things can drive you nuts. From my boss’ boss’ perspective, it’s just two more columns to a spreadsheet –what can be so hard about that? In fact, I thought the same thing when I looked at it.
Gets back to the “Excel Perspective” that I’ve blogged about before. If you can do it in excel, why does it take 4 months to do it on a server?
This is why.
--kevin
Friday, January 28, 2011
I DIDN'T DO IT!
Turns out that right after I get the email telling me my project has been accepted and approved by SourceForge and posted to their "OK" list, their site got hacked.
http://www.theinquirer.net/inquirer/news/1940350/sourceforge-takes-developer-services-security-breach
http://www.techeye.net/security/hackers-hit-sourceforge
Just for the record -- I didn't do it!
:)
Wait, let me practice.
"To the best of my recollection, Senator, I did not have any particpation in nor knowledge of the events described and on the advice of my...."
--kevin
http://www.theinquirer.net/inquirer/news/1940350/sourceforge-takes-developer-services-security-breach
http://www.techeye.net/security/hackers-hit-sourceforge
Just for the record -- I didn't do it!
:)
Wait, let me practice.
"To the best of my recollection, Senator, I did not have any particpation in nor knowledge of the events described and on the advice of my...."
--kevin
Saturday, January 22, 2011
Keep On Top and Raaaave reviews
Well, ok.. not so rave.
But I got an email from Source Forge saying that Keep On Top has been added to their "official" list of Windows products.
Said they:
"We are impressed with the quality of your product and encourage you to keep these high standards in the future"
..like they really looked at it :)
They did test it for spyware, malware, and otherware and proclaimed it "clean", which is good.
Just thought it was kinda fun and worth a blog entry.
cheers,
--kevin
But I got an email from Source Forge saying that Keep On Top has been added to their "official" list of Windows products.
Said they:
"We are impressed with the quality of your product and encourage you to keep these high standards in the future"
..like they really looked at it :)
They did test it for spyware, malware, and otherware and proclaimed it "clean", which is good.
Just thought it was kinda fun and worth a blog entry.
cheers,
--kevin
Thursday, January 20, 2011
Keep On Top
It’s been over 2 months since my last post, but I’m still kickin’.
The last 2 months has seen a lot activity – the holidays, a new job, some winter travel, a lot of football and a bit of geek stuff.
So for my first post of 2011, I decided to share some open source code I wrote. Here’s the problem space:
You’re doing something that requires attention, but not interaction. For me, this may involve watching a process run or tailing a log file. Or maybe it’s installing some new software. Whatever.
But I hate just sitting there watching the stuff. Who wants to sit and watch log files tail for 2 hours straight? All I really want to know is when it’s done or I want to see if it stops or gets any obvious errors. So I open up my email and fire off a couple. I pop open a browser. I get ping-ed on a chat client by a friend. And, maybe I play a computer game or something.
While I do this, the window I’m watching gets lost under the rest of them. So I … do what? I can randomly switch to the “watch window” and hope to catch it at the right time to see the error, I suppose. But what I really want is for that window to stay in sight while I’m doing something else.
So I wrote KeepOnTop. KeepOnTop starts up with a list of all your running applications. You pick one and it locks that window at the top of all the others. It does not give the window focus. And, in fact, the window stays on top even when you’re typing somewhere else.
The assumption is that you resize the window to be reasonably small and move it off to the side, Then you can type away at an email or whatever, while watching the log file tail. The only impact to the email app is that the part directly under the top window won’t be visible. Of course, you can move the top window anywhere you like anytime you want, so you can get by that.
KeepOnTop uses some native Windows APIs by importing user32.dll into C# as an “extern” and then exposing 3 or 4 static functions in it.
It’s not quite finished yet. I’m thinking about doing a bit of Windows explorer integration so you can right-click an executable and say “keepOnTop”, which would cause the exe to be run and automagically pushed to the top. But we’ll see.
Meanwhile, you can find it on SourceForge at
http://sourceforge.net/projects/keepontop/
The source is in the subversion area. The exe is in a zip file under the “files” area.
The last 2 months has seen a lot activity – the holidays, a new job, some winter travel, a lot of football and a bit of geek stuff.
So for my first post of 2011, I decided to share some open source code I wrote. Here’s the problem space:
You’re doing something that requires attention, but not interaction. For me, this may involve watching a process run or tailing a log file. Or maybe it’s installing some new software. Whatever.
But I hate just sitting there watching the stuff. Who wants to sit and watch log files tail for 2 hours straight? All I really want to know is when it’s done or I want to see if it stops or gets any obvious errors. So I open up my email and fire off a couple. I pop open a browser. I get ping-ed on a chat client by a friend. And, maybe I play a computer game or something.
While I do this, the window I’m watching gets lost under the rest of them. So I … do what? I can randomly switch to the “watch window” and hope to catch it at the right time to see the error, I suppose. But what I really want is for that window to stay in sight while I’m doing something else.
So I wrote KeepOnTop. KeepOnTop starts up with a list of all your running applications. You pick one and it locks that window at the top of all the others. It does not give the window focus. And, in fact, the window stays on top even when you’re typing somewhere else.
The assumption is that you resize the window to be reasonably small and move it off to the side, Then you can type away at an email or whatever, while watching the log file tail. The only impact to the email app is that the part directly under the top window won’t be visible. Of course, you can move the top window anywhere you like anytime you want, so you can get by that.
KeepOnTop uses some native Windows APIs by importing user32.dll into C# as an “extern” and then exposing 3 or 4 static functions in it.
It’s not quite finished yet. I’m thinking about doing a bit of Windows explorer integration so you can right-click an executable and say “keepOnTop”, which would cause the exe to be run and automagically pushed to the top. But we’ll see.
Meanwhile, you can find it on SourceForge at
http://sourceforge.net/projects/keepontop/
The source is in the subversion area. The exe is in a zip file under the “files” area.
Wednesday, November 10, 2010
threadPools again
Here's a supremely annoying ThreadPool undocumented/under-documented feature that cost me hours.
If you have a resource you're using -- say a database connection -- and you want to limit the resource -- say because you have hard limit on the number of simultaneous database connections you can open -- then you can limit the number of simultaneous threads that a ThreadPool can open by using the SetMaxThread method:
ThreadPool.SetMaxThread(X,Y);
All good. Only:
-- under-documented feature: If you set the max threads less than the number of CPU cores on your system, the setting is ignored. That is, if you're running on a quad-core machine, and you set the max threads to be 2, the ThreadPool assumes you don't know what you're talking about, assumes it can think for you, and disregards your setting.
-- un-documented feature: if you set the max threads less than the number of cores, the max threads setting *doesn't* default to the number of cores, it's ignored completely. Basically, the ThreadPool doesn't default to the lowest possible value, but ramps up the max threads to whatever it feels like it wants to do.
This makes the ThreadPool mostly useless.
Look, if I'm writing an app that uses no resources except the CPU, that's great. But who writes apps that don't use any resources.
Moreover, most software developers don't have any control over the hardware on which their app runs. If I'm a typical line of business developer, I'm writing code that is set up to run on a server somewhere against a database. Likely, I have no control over the server. And it can be upgraded at any time.
In the days of virtualization, an administrator can update the number of CPU cores to a virtual machine on the fly. So if my app runs on a server, and an unrelated app runs on same server, and unrelated app needs more horsepower, admins can add CPU cores without even telling me.
If they do that, then all of a sudden my app -- which was throttled to a small number of threads so that it wouldn't smash the database connections -- now has the MaxThreads set too low. In that case, ThreadPool completely ignores the setting and spins off a zillion threads if it feels like the CPU can take it... completely crushing the database.
It's so frustrating when Microsoft does this. They make a great product, with a great feature, then make it totally unusable in real-world, line-of-business solutions.
GRRRRRRRRRRRR
--kevin
Subscribe to:
Posts (Atom)