Taking the road less travelled
Monday, July 27, 2009
Sometimes making a rash decision, turns out to be quite fulfilling. I took a couple of photographs and amongst them were these 2 pictures. Taken on my way home, just outside Cape Town. I took a left turn at a certain intersection, instead of driving across, like I normally do.
Sometimes we should apply this to software development also. Try a different approach to a known solution. It might end up being more interesting.
Pre-order Windows 7
Thursday, July 23, 2009
No, you can’t. Not in South Africa anyway. I spent a good couple of minutes (maybe more than 20) this morning trying how to pre-order, order, buy, rent and/or lease Windows 7.
So I’ve concluded that Microsoft does not want to sell Windows 7 to us. The Microsoft South Africa website has a buy/offers/upgrade page, but this does not even work properly.
Click the link and… no. I did not mean “South Africa 404 mspx”.
I recently (8 months ago) purchased a new notebook pre-installed with Windows Vista. So for a couple of months I’ve been running Windows 7 RC instead. Do I want to run Windows 7 in the future? Yes. Do I want to buy it? Yes.
So I pose this question to Microsoft: Will you please sell Windows 7 to me? Now? On pre-order?
Paging records using the ROW_NUMBER() function in SQL Server 2005
Monday, October 27, 2008
Early this morning I was confronted with a question. In general I like questions. I don't always know the answer (contrary to popular belief), so it was one of those Monday morning questions that make you sit up and think for a couple of minutes.
How easy is it to implement paging in SQL Server?
I don't know. I have never had to use paging in SQL. I do know MySQL provides the LIMIT keyword that allow you to specify an offset with the amount of records you need. LIMIT 100,20 will return results 100 to 120.
What about SQL Server 2005. Well, there's an temporary table solution that I've heard of but haven't seen implemented, partly because I try to avoid temporary tables.
Well, we're in luck. SQL Server 2005 introduced a new function called ROW_NUMBER(). So how does it work?
select
result.Firstname,
result.Lastname,
result.Date
from
(select
Firstname, Lastname, Date,
row_number() over (order by Date asc) as row
from
RegisteredUsers) as result
where
result.row >= 20 and
result.row <= 30
From the MSDN entry: "Returns the sequential number of a row within a partition of a result set, starting at 1 for the first row in each partition."
So it returns a sequential row counter within a partition of a result set. The only major remark is that you have to specify the ORDER BY clause, because it determines the order in which rows are assigned their row numbers.
The stored procedure below takes everything into account. Calling it requires you to specify a page number and a page size. The result set is also limited by the TOP expression to limit the number of results. I think it might help improve performance on large result sets.
create procedure dbo.GetCustomersPage
@PageNumber int,
@PageSize int
as
begin
declare @Offset int
declare @Limit int
set @Offset = 1 + (@PageNumber - 1) * @PageSize
set @Limit = @Offset + @PageSize
select
result.Firstname,
result.Lastname,
result.Date
from
(select
top (@Limit)
Firstname, Lastname, Date,
row_number() over (order by Date asc) as row
from
RegisteredUsers) as result
where
result.row between @Offset and @Limit
end
I think this solution is really simple and straightforward. Comments are always welcome and appreciated.
Environment:
Microsoft ® Visual Studio 2008
Microsoft ® .NET framework 3.5
Microsoft ® Windows XP (SP3)
C# Asynchronous methods with CallBack
Monday, October 13, 2008
It has been quite a while since my last post, so I decided to create a follow-up to a post I made last year. At the time I showed how to overcome the “cross-thread operation not valid” problem when updating the user interface. For this post I decided to tackle something more or less along the same lines, but instead focusing more on how to perform an asynchronous operation with a callback.
When creating a single-threaded application we normally have to wait for a long-running operation, such as a call to the database, to complete before we can update the user interface again. This creates an application that appears to be slow and unresponsive. The reason is that the long-running operations block other operations from continuing.
So what do we do? Using C# it is fairly straightforward to delegate long-running operations to background threads, so that our foreground thread updating the user interface stays responsive and allow other operations to be completed.
For this post I chose to show the how to execute a callback when an asynchronous method completes. There are other methods to use such as using the EndInvoke() Call Pattern, using WaitHandles to Wait for the Call to complete or the Polling Call Pattern. I find a Callback makes the most sense to me.
From my experience I found the following events occur the most in the type of applications I write:
- A control is clicked, indicating that some long-running operation will be fired
- Controls on the user interface needs to be set
- Long-running operation is started
- Long-running operation retrieves/generates data/updates user interface and/or performs magic
- Long-running operation ends
- Controls on the user interface needs to be set/populated
If we look at my code example, the above-mentioned steps are mapped to the following methods:
- private void buttonGo_Click(object sender, EventArgs e)
- private void SetFormControls(bool Enabled) in Step 1
- private bool SomeLongOperation() in Step 1
- private bool SomeLongOperation()
- private void SomeLongOperationCallBack(IAsyncResult result)
- private void SetFormControls(bool Enabled) in Step 5
Now for the code. I've (over-)commented the code to help explain. The example starts an asynchronous operation, updates a control on the form and executes a callback when done. It's a simple example, but I am of the opinion that it covers all of the basics.
using System;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplicationDemo
{
public partial class frmDemo : Form
{
public frmDemo()
{
InitializeComponent();
}
// Creates a delegate with the same signature as the method used for a long operation
// In this case we'll use SomeLongOperation()
private delegate bool SomeLongOperationDelegate();
// Creates a delegate with the same signature as the method used to update the UI
// In this case we'll use UpdateUIHelper(string value)
private delegate void UpdateUIDelegate(string value);
// Creates a delegate with the same signature as the method used to set form controls
// In this case we'll use SetFormControls(bool Enabled)
private delegate void SetFormControlsDelegate(bool Enabled);
/// <summary>
/// User actions start the long-running operation
/// Step 1, 2 and 3
/// </summary>
private void buttonGo_Click(object sender, EventArgs e)
{
SetFormControls(false);
this.UpdateUI("Starting...");
// create an instance of SomeLongOperationDelegate
SomeLongOperationDelegate someLongOperationDelegate = new SomeLongOperationDelegate(this.SomeLongOperation);
// start asynchronous operation, pass someLongOperationDelegate as a parameter, so we can get it back later on callback
someLongOperationDelegate.BeginInvoke(new AsyncCallback(this.SomeLongOperationCallBack), someLongOperationDelegate);
}
/// <summary>
/// Sets any controls on the form that you want to have set prior to starting the long operation
/// </summary>
/// <param name="Enabled">Enable or disable controls</param>
private void SetFormControls(bool Enabled)
{
// update any controls here, if you want to (such as enable or disable controls)
// this.buttonGo.Enabled = Enabled;
}
/// <summary>
/// Long operation such as a call to the database
/// Step 4
/// </summary>
/// <returns>bool value to indicate success</returns>
private bool SomeLongOperation()
{
// perform some longish operation
for (int i = 1; i < 8; i++)
{
this.UpdateUI(
new StringBuilder("Operation busy ").
Append(i.ToString()).
Append("... (Managed TID: ").
Append(Thread.CurrentThread.ManagedThreadId.ToString()).
Append(")").ToString());
Thread.Sleep(150);
}
return true;
}
/// <summary>
/// CallBack for the someLongOperationDelegate instance
/// Step 5 and 6
/// </summary>
/// <param name="result">IAsyncResult object</param>
private void SomeLongOperationCallBack(IAsyncResult result)
{
// original delegate passed in the asyncState parameter, get it back here
((SomeLongOperationDelegate)result.AsyncState).EndInvoke(result);
// update the user interface
this.UpdateUI(
new StringBuilder("CallBack (Managed TID: ").
Append(Thread.CurrentThread.ManagedThreadId.ToString()).
Append(")").ToString());
// start an asynchronous operation to set the controls on the form
this.BeginInvoke(new SetFormControlsDelegate(this.SetFormControls), new object[] { true });
}
/// <summary>
/// Checks whether or not an Invoke is required and calls the method accordingly
/// </summary>
/// <param name="value">value of string to go into the listbox</param>
private void UpdateUI(string value)
{
// if the calling thread is not the same thread that created the controls to be updated
// call an Invoke to update controls
if (this.InvokeRequired)
this.Invoke(new UpdateUIDelegate(this.UpdateUIHelper), new object[] { value });
else
this.UpdateUIHelper(value);
}
/// <summary>
/// Updates the user interface with whatever needs to be updated
/// </summary>
/// <param name="value">value of string to go into the listbox</param>
private void UpdateUIHelper(string value)
{
listboxResults.Items.Add(
new StringBuilder(value).
Append(" (Parent Managed TID: ").
Append(Thread.CurrentThread.ManagedThreadId.ToString()).
Append(")").ToString());
listboxResults.SelectedIndex = (listboxResults.Items.Count - 1);
}
}
}
Some afterthoughts:
- Make sure that you understand delegates and their use. They are very helpful and are needed when you want to make more use of events you application.
- Disable the controls that initiate the long-running operation if they are only needed for that purpose. Other controls such are grids or items that are updated to indicate progress, should be visible. Grids or controls populated with large amounts of data, may want to made invisible while the long-running operation is populating them.
- Make sure that you understand how Winforms managed threads are used. It will help you understand why you need to Invoke to update controls.
- When using BeginInvoke on a delegate, make sure you call EndInvoke to free any resources. When doing a this.BeginInvoke(...) and there are no results to harvest, you do not need to call EndInvoke(). Chris Sells has a paragraph or two in his book, Windows Forms Programming in C#. There are numerous discussions on BeginInvoke/EndInvoke available on the Internet, but from my experience, when following this simple rule, you should be ok.
Please feel free to comment on this post. It is always interesting to hear the opinions from other people.
Environment:
Microsoft ® Visual Studio 2008
Microsoft ® .NET framework 3.5
Microsoft ® Windows XP (SP3)
Labels: C#, Delegates, Events, Forms, Microsoft, Software Development, Threads
Base32 encoding in C#
Friday, August 22, 2008
In my previous post, I hashed a C# uint value using the sdbm hashing function. But what if you want to convert the hashed value to Base32? Unfortunately there's no built-in function to accomplish this, but help is at hand.
I based my function on this implementation, making only 1 or 2 minor changes. You may also refer to RFC3548 for more reading on the subject.
/// <summary>
/// Encode to base 32 according to RFC3548
/// </summary>
/// <param name="data">byte array to encode</param>
/// <returns>string value</returns>
public static string Base32Encode(byte[] data, int size)
{
int i = 0;
int index = 0;
int digit = 0;
int current_byte;
int next_byte;
StringBuilder result = new StringBuilder();
while (i < data.Length)
{
// unsign
current_byte = (data[i] >= 0) ? data[i] : (data[i] + 256);
// is the current digit going to span a byte boundary
if (index > (IN_BYTE_SIZE - OUT_BYTE_SIZE))
{
if ((i + 1) < data.Length)
next_byte = (data[i + 1] >= 0) ? data[i + 1] : (data[i + 1] + 256);
else
next_byte = 0;
digit = current_byte & (0xFF >> index);
index = (index + OUT_BYTE_SIZE) % IN_BYTE_SIZE;
digit <<= index;
digit |= next_byte >> (IN_BYTE_SIZE - index);
i++;
}
else
{
digit = (current_byte >> (IN_BYTE_SIZE - (index + OUT_BYTE_SIZE))) & 0x1F;
index = (index + OUT_BYTE_SIZE) % IN_BYTE_SIZE;
if (index == 0)
i++;
}
result.Append(alphabet[digit]);
}
// trim the result to a specific size
return result.ToString().Substring(0, size <= result.Length ? size : result.Length);
}
If you have a specific question (not necessarily related to this post), let me know and we can see what solutions are available.
Environment:
Microsoft ® Visual Studio 2008
Microsoft ® .NET framework 3.5
Microsoft ® Windows XP (SP3)
sdbm hashing in C#
Thursday, August 21, 2008
sdbm - Substitute DBM or Berkeley ndbm for Every UN*X Made Simple is a hashing function I have never used before. To be honest, hashing is something I hardly ever *cough*never*cough* use.
So, how do you convert the simple sdbm hashing function from C++ to C#. I'm not asking. I'm going to tell you, because from my search in Google, it seems not a lot of people have attempted. Luckily I remember most of the C++ basics. De-referencing (pointers), addresses... you know, the things you tend to forget when working with C#.
C++ code:
static unsigned long sdbm(unsigned char *str)
{
unsigned long hash = 0;
int c;
while (c = *str++)
hash = c + (hash << 6) + (hash << 16) - hash;
return hash;
}
C# code:
/// <summary>
/// sdbm hashing function
/// </summary>
/// <param name="byteArr">Array of bytes to hash</param>
/// <returns>uint</returns>
private uint sdbm(byte[] byteArr)
{
uint hash = 0;
foreach (byte b in byteArr)
hash = b + (hash << 6) + (hash << 16) - hash;
return hash;
}
The trick is to simply pass an array of bytes to the C# function. A byte in C# has the same size as the unsigned char datatype in C++. But how do I pass an uint object as an array of bytes? Simple.
uint value = GetSomeIDFromSomewhere();
uint Hash = sdbm(BitConverter.GetBytes(value));
The C# BitConverter class converts a value to an array of bytes, which is exactly what we needed for the sdbm function.
That's it. For the next post, I'll encode the hashed value to Base32. And as always, leave a comment if you found this useful.
Environment:
Microsoft ® Visual Studio 2008
Microsoft ® .NET framework 3.5
Microsoft ® Windows XP (SP3)
3G Data Charges
Saturday, July 5, 2008
Earlier I read a post by Jonathan Endersby on how Vodacom is violating Facebook copyright, by displaying/adding advertisements on the mobile versions of Facebook.
Someone made the following comment on his post:
Plus, does it result in extra bandwidth charges for the consumer? (Those little bits of information do add up over time.)
Yes, those little bits do add up over time, and recently I've Hannes and I also started wondering about those
The data bundle on 2779....... has already been depleted and out-of-bundle rates are applicable...
SMS's that I get whenever I've used my 3G data bundle.
These SMS's always arrive a day or two after I've depleted my bundle. I would have liked to be cut off immediately when I used my data bundle. If Vodacom charges me and everyone else the out-of-bundle rates for a day or two, they stand to generate a lot of additional income.
Quite of clever way of generating income. Just delay those "out-of-bundle" SMS's a day or two. Or am I paranoid?