Wednesday, December 20, 2006
Asymmetric Accessor Accessibility means you can do this:
public string Name
{
get { return this.name; }
protected set { this.name = value; }
}
Is that cool, or what! There a few caveats, so be sure to read the Language Spec page on this topic.
Thursday, August 31, 2006
I can feel it. I was running the other day, The Distance playing in my ear-buds, and I caught a whiff of it. The scent of rain and plants and cold pavement and other things I can’t remember, a barbeque, maybe. The sun was shining, the clouds were awesome. I had clear road in front of me and nothing to do but run. I had to laugh – a bit maniacally, I admit. Then the moment passed and all returned to the way it was. But, oh yes, fall is here.
Wednesday, August 23, 2006
Bloody useful, this code. Especially when threads or timers are involved.
class Tracer
{
private Tracer() { }
public static void WriteTracedDebugLine(string message)
{
StackTrace stack = new StackTrace();
string caller = stack.GetFrame(2).GetMethod().Name;
string callee = stack.GetFrame(1).GetMethod().Name;
if(message != null && message.Length > 0)
Debug.WriteLine(message, caller + " -> " + callee);
else
Debug.WriteLine(caller + " -> " + callee);
}
}
Monday, August 21, 2006
Anonymous methods are a great new feature in .Net 2. Another great new feature is the ParameterizedThreadStart delegate. Since the ParameterizedThreadStart delegate is just a delegate, these two concepts can be combined to effectively create an asynchronous anonymous method – an anonymous thread, if you will. You can spin off a chunk of code to run asynchronously without having to put it into a separate function. Check out the following code:
private void AddAsync(int a, int b)
{
//Define the code we want to run asynchronously.
// Note that an anonymous delegate works just
// as well as a ParameterizedThreadStart
Thread t = new Thread(delegate(object paramArray)
{
//get the data we passed into the thread
object[] param = paramArray as object[];
//do your long-running process here (this part runs asynchronously)
Thread.Sleep(1000);
int result = (int)param[0] + (int)param[1];
//when we're done with our asynchronous processing, hit the callback function
this.Invoke(new AdditionDoneDelegate(AdditionDone), new object[] { result });
});
//start running the asynchronous code
t.Start(new object[] { a, b });
}
private delegate void AdditionDoneDelegate(int result);
private void AdditionDone(int result)
{
//this gets called when your asynchronous processing is done
MessageBox.Show(result.ToString());
}
Another cool application for this is to create a partially asynchronous function. You can enclose a long running data access operation, for example, within an anonymous thread and use a non-blocking wait (a mutex) to keep the rest of the function from running until the operation is complete. That’s right, you can make just part of your function run asynchronously:
private void AddPartiallyAsync(int a, int b)
{
int result = 0;
Mutex mutex = new Mutex();
Thread t = new Thread(delegate()
{
//do your long-running process here (this part runs asynchronously)
Thread.Sleep(1000);
result = a + b;
//when we're done with our asynchronous processing, release the mutex
mutex.ReleaseMutex();
});
//start running the asynchronous code
t.Start(new object[] { a, b });
//non-blocking-wait here until the thread is done
mutex.WaitOne();
//continue the function here...
MessageBox.Show(result.ToString());
}
Notice that the code inside the anonymous asynchronous method can access variables defined in the surrounding function. I fully expected there to be scoping that would prevent this. But, amazingly, it works. However, I wouldn’t be surprised if this behavior was eliminated in a later version of the framework. Another surprising part of all this is how well the debugger handles it. Simply amazing!
Monday, March 27, 2006
Previously, the discovery of what SQL servers exist on your network was quite a task. The general approach involved PInvoke. Yeah. Now, it .Net 2, it's a one-liner. Sweet!
public
List<SQLServer> GetServers()
{
DataTable dt = SqlDataSourceEnumerator.Instance.GetDataSources();
List<SQLServer> servers = new List<SQLServer>();
foreach(DataRow row in dt.Rows)
{
SQLServer svr = new SQLServer();
svr.Name = row.ItemArray[0] as string;
svr.InstanceName = row.ItemArray[1] as string;
svr.IsClustered = row.ItemArray[2] as string;
svr.Version = row.ItemArray[3] as string;
servers.Add(svr);
}
return servers;
}
Hmm... I just noticed that they used a singleton with one method instead of just making GetDataSources static. Odd.
Tuesday, March 07, 2006
Joel likes to run off on little rants right in the middle of an article about whatever. Usually they're great. Sometimes they are dead on:
“If you enjoy programming computers, count your blessings: you are in a very fortunate minority of people who can make a great living doing work they enjoy. Most people aren't so lucky. The very idea that you can "love your job" is a modern concept. Work is supposed to be something unpleasant you do to get money to do the things you actually like doing, when you're 65 and can finally retire, if you can afford it, and if you're not too old and infirm to do those things, and if those things don't require reliable knees, good eyes, and the ability to walk twenty feet without being out of breath, etc.”
Monday, February 27, 2006
The ListView control has a flicker issue. The problem appears to be that the control's Update overload is improperly implemented such that it acts like a Refresh. An Update should cause the control to redraw only its invalid regions whereas a Refresh redraws the control’s entire client area. So if you were to change, say, the background color of one item in the list then only that particular item should need to be repainted. Unfortunately, the ListView control seems to be of a different opinion and wants to repaint its entire surface whenever you mess with a single item… even if the item is not currently being displayed. So, anyways, you can easily suppress the flicker by rolling your own as follows:
class
ListViewNF : System.Windows.Forms.ListView
{
public ListViewNF()
{
//Activate double buffering
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
//Enable the OnNotifyMessage event so we get a chance to filter out
// Windows messages before they get to the form's WndProc
this.SetStyle(ControlStyles.EnableNotifyMessage, true);
}
protected override void OnNotifyMessage(Message m)
{
//Filter out the WM_ERASEBKGND message
if(m.Msg != 0x14)
{
base.OnNotifyMessage(m);
}
}
}
Easy but with a couple little catches. If you need to do this, I recommend reading the help on the various properties of ProcessStartInfo. This code runs a console window that is visible to the user. There is a way to run commands by cmd.exe without actually showing a window... and I'm sure you can figure that out if you're interested enough. This should getcha started.
//set up to show a console window and send input to it
string pathToCmdExe = Environment.GetEnvironmentVariable("COMSPEC");
ProcessStartInfo psi = new ProcessStartInfo(pathToCmdExe);
psi.RedirectStandardInput = true;
psi.UseShellExecute = false;
//open the console windown
Process console = Process.Start(psi);
//send it a command
console.StandardInput.WriteLine("dir");
//TODO: Send more commands, read the results, etc.
//close the console window
console.Close();
Tuesday, February 14, 2006
It’s been too long. I can’t believe it’s been over a month since I did a post here. Well, that’s not actually true. I’ve posted a few random photos from my phone. I’ll probably post a whole lot more of those because it’s such an interesting and fun medium. You don’t have to worry about image quality (it’s guaranteed to be bad) so you’re free to focus on composition. Just catch some interesting light or an unusual angle and Blam! You’ve got a cheap (free), modern, lazy form of impressionism… if you will. Actually most of the photos are awful and only make sense to about three people. But hey it’s fun, easy, and no paint stains. Brilliant! Also, if you’re feeling particularly adventurous (and you don’t mind lugging a scanner around) you can make some really… really… well, just go check out the web site. It’s cool stuff.
Thursday, January 05, 2006
Say you want to call a method on a control on your form from a thread... For example, you might want to populate a ListBox with a lot of data or with data from a really slow data source. In these cases you'll probably be using a seperate thread to get the data because it's generally a Bad Idea to block (freeze) your UI while you wait for all the data to come in. Especially if the data is of an indeterminate length. So, one way to get at that ListBox from a seperate thread it is to use Control.Invoke:
private void StartAsynchLoad()
{
this.lstDatabases.Items.Clear();
//load the databases asynchronously
Thread t = new Thread(new ThreadStart(LoadDatabasesThread));
t.Start();
}
private void LoadDatabasesThread()
{
//load the databases into the listbox
string dataSource = this.txtServer.Text;
string [] names = DataAccess.Instance.GetDatabases(dataSource);
foreach(string name in names)
{
this.Invoke(new AddItemDelegate(AddItem), new object[]{name});
}
}
private delegate void AddItemDelegate(string text);
private void AddItem(string text)
{
this.lstDatabases.Items.Add(text);
}
So, what if you need to pop up a dialog box that could potentially abort the application before you pop up your main form? There are usually no good reasons to construct objects that you don't intend to use. That would include opening a Form which will immediately be closed. But is the following acceptable? I know it's possible... I'm doing it. But what could go wrong in this situation? This must be bad in some way that I haven't found yet.
[STAThread]
static void Main()
{
//let the user choose a database before we start the program
DialogResult dr = frmDatabases.Instance.ShowDialog();
if(dr == DialogResult.OK)
Application.Run(new frmMain());
}
Tuesday, December 20, 2005
So, I don’t really have anything to write about that wouldn’t be a rant about boredom, job satisfaction, ridiculous inefficiency, or one of the other states of the various affairs with which I am associated at this juncture. I wish I could post some cool code samples, but that would imply that I had actually written some interesting code lately… which I haven’t. But never fear, all this lack of momentum has prompted me to take much more of an interest in my side projects, which were all previously on hold. I have two main projects in mind which should be pretty slick. They should also generate some interesting bloging material before long. Stay tuned... cool stuff is to coming soon!
Tuesday, December 13, 2005
Monday, December 05, 2005
... and I'd probably be heading back today, if only my car wasn't in the shop

[Vista Express web-cam pic from this morning]
So... last week I got a new
job, had a great day of
snowboarding, finished the
book I was reading, and saw a
good movie with one of my roommates. What a great way to end the week.