Peter Norvig has a great essay on the naivete that a person can teach him/herself how to program in [insert short time frame here]. I would definitely have to agree. Even 4 years at college barely gets a person to a junior developer level.
I guess that’s one of the main reasons I like programming, I love to continually learn new stuff, and in the software development world, there will always be something new to learn.
|
Posted by
admin |
Categories:
Uncategorized |
I created a build script for a .Net 3.5 project today and received the following error
Target framework: Microsoft .NET Framework 2.0
Target(s) specified: build
[echo] getting into the script
[property] Target framework changed to "Microsoft .NET Framework 3.5".
BUILD FAILED
INTERNAL ERROR
System.NullReferenceException: Object reference not set to an instance of an object.
at NAnt.Core.FrameworkInfo.get_Version()
at NAnt.Core.Project.UpdateTargetFrameworkProperties()
at NAnt.Core.Tasks.PropertyTask.ExecuteTask()
at NAnt.Core.Task.Execute()
at NAnt.Core.Project.InitializeProjectDocument(XmlDocument doc)
at NAnt.Core.Project.Execute()
at NAnt.Core.Project.Run()
When I changed the nant.settings.currentframework property in the build script from "net-3.5" to "net-2.0" this error went away. (Of course I received an error from the .Net 2.0 version of MSBuild since it was trying to compile .Net 3.5 code, but it let me know that there was a problem within NAnt dealing with the "net-3.5" setting)
I didn’t want to dig through the NAnt source code to figure out what the problem was, so I did some googling and found the following blog entry from Jeffrey Palermo. In the comments a person shared he was receiving the same error and a few comments below that a person shared that they updated the "net-3.5" framework section in the Nant.exe.config file with Jeffrey’s version that is located at this link.
I reran the build and NAnt worked like a charm.
If I had a lot of ambition I would try to figure out the exact cause for this error and fix my build script, but today I just don’t have that much ambition.
|
Posted by
admin |
Categories:
Hacks,
nant |
I’ve had to copy and paste a file from a remote desktop connection to my computer a few times, and I always forget how to enable this functionality so I’m creating this post so I can remember.
At the Remote Desktop Connection window, click on the "Options" button
Then click on the "Local Resources" tab
In the "Local devices and resources" group box, make sure the "Clipboard" checkbox is checked
Also in the "Local devices and resources" group box, click on the "More" button
Within the TreeView, expand the "Drives" node and select the drives from the remote computer that you want to copy and/or paste files to.
That’s it. Now log in and you should be able to copy and paste files between computers.
|
Posted by
admin |
Categories:
Uncategorized |
I’ve spent a few hours these past couple days researching how to raise events asynchronously, and I would like to share my findings.
Raising an event synchronously in the same thread is pretty simple.
public class FooClass
{
public event EventHandler FooEvent;
private void OnFooEvent()
{
if (FooEvent != null)
{
FooEvent(this, new EventArgs());
}
}
}
The above code raises the event and all subscribers to the event are notified and do their respective processing. However, since the event is raised in the same thread, OnFooEvent() cannot proceed until all the subscribers to the event do their processing. This can cause an unwanted delay, specifically if the class raising the event is a Windows form, which would cause the form to freeze and be unresponsive to the user.
Raising events asynchronously lets the event subscribers do their processing in another thread and allows the thread that raised the event to continue processing. And in the case of a form raising an event, the form can still be responsive to user input as the event subscribers do their processing in the background.
Below is a code example on raising an event asynchronously.
public class FooClass
{
public event EventHandler FooEvent;
private void OnFooEvent()
{
if (FooEvent != null)
{
FooEvent.BeginInvoke(this, new EventArgs(), FooEventCallBack, FooEvent);
}
}
/// This method is called when the event subscriber has finished its processing
private void FooEventCallback(IAsyncResult Result)
{
EventHandler raisedEvent = (EventHandler)Result.AsyncState;
raisedEvent.EndInvoke(Result);
}
}
You will notice raising an event asynchronously is a bit more involved. First off, the BeginInvoke() method is called (FooEvent.BeginInvoke()) instead of calling the delegate/event itself (FooEvent(this,new EventArgs())). BeginInvoke() raises the event in another thread. The first two arguments are the event arguments. The third argument is the callback method that will be called when the event subscriber has finished its processing. The last argument in BeginInvoke() is the object you want to send to the callback method, and it can be null if so desired. Once BeginInvoke() is called, FooClass continues its processing as the event subscribers are notified in a separate thread.
Now lets take a look at the FooEventCallback() method that is called when the event subscriber has finished its processing. This method takes 1 argument of type IAsyncResult. You must pass in this argument to the EndInvoke() method of the event to free up resources and prevent a memory leak. The AsyncState property on this argument references the last object that was passed into BeginInvoke() (in this case the FooEvent).
One shortcoming of the above code is that it will only work if there is one subscriber to the event. If there are multiple subscribers, then you will receive an ArgumentException error stating “The delegate must have only one target.” To get around this, you must raise the event individually for each target. Take a look at the code below.
public class FooClass
{
public event EventHandler FooEvent;
private void OnFooEvent()
{
if (FooEvent != null)
{
Delegate[] subscribers = FooEvent.GetInvocationList();
foreach (EventHandler subscriber in subscribers)
{
subscriber.BeginInvoke(this, new EventArgs(), FooEventCallBack, subscriber);
}
}
}
/// This method is called when the event subscriber has finished its processing
private void FooEventCallback(IAsyncResult Result)
{
EventHandler raisedEvent = (EventHandler)Result.AsyncState;
raisedEvent.EndInvoke(Result);
}
}
We get the list of subscribers by calling GetInvocationList() on the event. This returns an array of type Delegate. You will notice, however, that within the foreach loop the subscribers are cast to their specific delegate type (foreach (EventHandler subscriber in subscribers)) instead of the base Delegate type (foreach (Delegate subscriber in subscribers)). This has to be done so the event can be raised asynchronously. The base Delegate type does not have a BeginInvoke() method.
Hopefully this helps others with raising event asynchronously. The you download the attachment below to view example source code of raising event asynchronously in action.
EventCallbacks Example Code
|
Posted by
admin |
Categories:
Uncategorized | Tagged:
callbacks,
events,
threads |
I have grown to love the DataGridView and the simplicity it provides in displaying lists of objects. All you have to do is set the DataGridView’s DataSource property to the list that you want displayed and it does everything else.
Here’s an example
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
List<Person> people = new List<Person>();
people.Add(new Person() { FirstName = "John", LastName = "Smith" });
people.Add(new Person() { FirstName = "John", LastName = "Doe" });
people.Add(new Person() { FirstName = "Jane", LastName = "Does" });
dataGridView1.DataSource = people;
}
}
And here is the screenshot:

Yesterday I had a list that contained simple string objects (List<string>) and I wanted to display the list in a DataGridView, but I was thoroughly frustrated when the DataGridView did not show the string items, but instead displayed the Length of each string item. Below is an example.
public Form1()
{
InitializeComponent();
List<string> fullNames = new List<string>();
fullNames.Add("John Smith");
fullNames.Add("John Doe");
fullNames.Add("Jane Doe");
dataGridView1.DataSource = fullNames;
}
And here is the screenshot:

Now why in the world would I want to know the length of a string object? I could care less. I just want the DataGridView to display the string itself, not how long it is.
I thought there was an easy way around this, so I started googling… and googling, and to my dismay I did not find a work around.
I did find the reason that the DataGridView displays the length. When a DataGridView is bound to a list, it uses reflection to display all the public properties of the object type in the list. In the first example, the Person type contained 2 properties: FirstName and LastName. And those were displayed by the DataGridView. The second example contained a list of string items, and it turns out that the only public property for strings is the Length property. It does not have a Value property. It does have a ToString() method, but that is a method, not a property.
There is a workaround, but it’s annoying. Basically, you need to create a type that has a public property that returns the string value. Below is an example
public class StringValue
{
public StringValue(string Value)
{
this.Value = Value;
}
public string Value { get; set; }
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
List<StringValue> fullNames = new List<StringValue>();
fullNames.Add(new StringValue("John Smith"));
fullNames.Add(new StringValue("John Doe"));
fullNames.Add(new StringValue("Jane Doe"));
dataGridView1.DataSource = fullNames;
}
}
And now the DataGridView correctly shows the string items

I wish the DataGridView provided the option to manually set which properties, and even method return values, to display. I don’t think that will happen any time soon, so I guess I will just have to deal with the hack.
|
Posted by
admin |
Categories:
Uncategorized | Tagged:
Annoyances,
Hacks |