SyntaxHighlighter

Thursday, December 10, 2009

C#: Calling/Overriding Grandparent Base Class Methods

I use a base class for 99% of my ASP.Net pages, which executes a few operations in the OnInit() method. Here's a simplified version:
public abstract class BasePage : System.Web.UI.Page, IBasePage
{
protected override void OnInit(EventArgs e)
{
// Do stuff
Method1();
Method2();
Method3();

// Call System.Web.UI.Page.OnInit
base.OnInit(e);
}
}
This works great for all my child classes/pages, but there are a few scenario's where I'd only like to call a specific set of methods, as illustrated here:
public class MyPage: BasePage
{
protected override void OnInit(EventArgs e)
{
// Ommit Method2()
Method1();
Method3();

// This calls BasePage.OnInit, which makes
// redudant calls to Method1() and Method3(),
// and the undesired call to Method2().

base.OnInit(e);
}
}
It is obvious that the last base.OnInit(e) call will have the undesired effect. Being 6:23 PM, after coding all day, my fried brain's initial thought was to bypass the base class' OnInit(e) method and to call the grandparent's OnInit(e) method directly.

An obvious faux pas. Whenever venturing into the "grandparent" or "grandchild" realm (more than one degree of seperation), you're probably going down the wrong path.

The proper and easy approach is merely to move the method calls out to a seperate method, which one overrides in the child class like so:
public abstract class BasePage : System.Web.UI.Page, IBasePage
{
protected override void OnInit(EventArgs e)
{
// Do stuff
Initialize();

// Call System.Web.UI.Page.OnInit
base.OnInit(e);
}

protected virtual void Initialize()
{
Method1();
Method2();
Method3();
}
}

public class MyPage: BasePage
{
protected override void Initialize()
{
// Do stuff
Method1();
Method3();
}
}

Monday, December 7, 2009

GNU Plot and SVG: Change the terminal size and font

Again, not really a dev related issue, but I did not find much info online regarding this.

When using gnuplot to create SVG files, one use the set term svg command that sets the following defaults:
gnuplot> set term svg
Terminal type set to 'svg'
Options are 'size 640 480 fixed fname 'Arial' fsize 12 butt '

One can speficy custom parameters to get the desired output:
gnuplot> set term svg size 640,350 fname 'Times New Roman' fsize 10
Terminal type set to 'svg'
Options are 'size 640 350 fixed fname 'Times New Roman' fsize 10 butt '

Monday, November 23, 2009

Type 'DataContract' is not defined

This error can be resolved by adding a reference to the .net System.Runtime.Serialization assemly and also importing this namespace in the file where applicable.

Also, applies to Type 'DataMember' is not defined.

Tuesday, November 3, 2009

VB.NET: Check if an event handler has been assigned to a method

This is how one checks if an event handler (or any delegate handler for that matter) has been assigned to a method.

' Create the delegate
Public Delegate Sub UpdateEvent()
' Create a handler
Public Update As UpdateEvent

' ...
' Rest of the class
' ...

' Check if the event handler has been assigned to
If Not Update Is Nothing Then
Update()
End If

'SyncLock' operand cannot be of type '' because '' is not a reference type

Just had this little error in VB.NET:

Error Message: 'SyncLock' operand cannot be of type 'Boolean' because 'Boolean' is not a reference type.
Error ID:
BC30582

I tried to change the variable to type Object, but this seems to be converted to Boolean during runtime, which raises the same error.

A clumsy way around this is to simply use a Boolean array of length 1. There must be a better way though, and I'll update this post when I find a better approach.

Yes, I did say vb. Yes, I am ashamed. Client's request.


Update:
Ok here's the deal on using SyncLock or Monitor.Enter (mutex) with value types such as Boolean, Integer, or Double. One is not supposed to lock value types, as they do not have the necessary overhead fields (MethodTablePointer and SyncBlockIndex) to allow a lock to be acquired. One gets around this issue, by creating a reference type, which acts as a flag when the value type is being written to. More on this at the end of Jeffery Richter's article on Safe Thread Synchronization.

Friday, October 23, 2009

An error occurred while reading the app.config file

I edited my app.config file manually, which did not seem to agree with VS. Even though the XML was valid, I received the message: An error occurred while reading the app.config file. The file might be corrupted or contain invalid XML. Despite this message the code will still run, but its just annoying.

This is a known bug, which I managed to get rid off by removing the project from the solution, restarting Visual Studio and adding the project again.

Thursday, October 22, 2009

SQL Server: Automated log file maintenance

Ok you've all seen it before. You remote desktop onto a client's sql server to upload your app, when your upload fails due to a lack of disk space. Darnit! So you have to reduce the LDF's, which has grown to be several GBs large.

The following little script will reduce all the non-system db's log files. One can also schedule this script as a job that automatically reduces the log files. (Disclaimer: Read-up on the function log files fulfil before simply using this script. I would not recommend running this on critical production systems.)

-- This gets us all on the same page
use [master]

-- Define some variables
declare @statement varchar(2000)
declare @dbname sysname
declare dbname_cursor cursor for

-- Select all non-system db's
select [name] from master.dbo.sysdatabases where
[name] <> 'master' and
[name] <> 'model' and
[name] <> 'msdb' and
[name] <> 'tempdb'

-- Iterate through each db record
open dbname_cursor
fetch next from dbname_cursor into @dbname
while @@fetch_status <> -1
begin
select @statement = ''
select @statement = @statement + 'use ' + @dbname + '; '

-- Backup db by runcating only (will not reduce physical file size)
select @statement = @statement + 'backup log ' + @dbname + ' with truncate_only; '

-- Get the db log file name
select @statement = @statement + 'declare @log_file varchar(2000); '
select @statement = @statement + 'select @log_file = [name] from sys.database_files where type_desc = ''LOG''; '

-- Reduce the physical file size
select @statement = @statement + 'exec(''dbcc shrinkfile ('' + @log_file + '', 0)''); '
exec(@statement)
fetch next from dbname_cursor into @dbname
end
close dbname_cursor
deallocate dbname_cursor