Dan Rigsby – Coding Up Style

Developer.Speaker.Blogger

Archive for August, 2008

Async Operations in Wcf: Handling Exceptions

Posted by Dan Rigsby on 28th August 2008

Async Operations in Wcf Series:
Part 1: Event Based Model
Part 2: IAsyncResult Model (Client-Side)
Part 3: IAsyncResult Model (Server-Side)
Part 4: Canceling Operations
Part 5: Handling Exceptions

This is the fifth in a five part series on asynchronous operations in Wcf.  If you are new to this series, you might want to read the first section of part one to get an introduction to this post: http://www.danrigsby.com/blog/index.php/2008/03/18/async-operations-in-wcf-event-based-model/

What happens when there is an exception

We have covered the ins and outs of working with asynchronous operations.  But what happens in the unexpected happens?  What happens if an Exception or FaultException occurs on the server? There are basically two situations:

  1. The exception is thrown before the thread is queued or before the thread context switch has happened.  This would still be on the users’s initiated thread.
  2. The exception is thrown during the actual asynchronous operation on a different thread. This would be on some internal thread in the WCF service.

In situation 1, this acts like any other service call.  Since the exception occurred on the same thread the client initiated, it is simply propagated back to the client like any other exception.

In situation 2, the exception occurs on a separate thread, so the client isn’t directly notified. Instead the server caches the exception and signals the client that the operation is complete.  The client in turn will call its end operation completion method which will throw the exception back to the client.  Keep in mind though, that if the exception is fatal to the service and beyond recovery, it can crash the service process itself.

Exception example

An example of this can be shown with a simple service that calculates a square root.  In the call on the server, we have it wait 20 seconds before returning the result.  However, if we throw an exception before the wait period, the client will get signaled immediately. 

public double GetSquareRoot(double value)
{
    // Throwing exception here causes the server to signal to 
    // the client that the operation is complete and the exception
    // is rethrown on the client
    throw new FaultException("Fault before queuing thread.");

    Thread.Sleep(20000); // Wait 20 seconds

    return Math.Sqrt(value);
}
 

AsyncException

You can download this full example here: http://www.danrigsby.com/Files/Rigsby.WcfAsyncOperationExceptions.zip

DotNetKicks Image

Posted in Wcf | 10 Comments »

New Webcast: Date & Times in .Net 3.5

Posted by Dan Rigsby on 27th August 2008

screencast I have a new 9 min 0 sec training webcast out over the new DateTimeInfo and TimeZoneInfo structs in .Net 3.5.  This video complements two of my recent blog posts:

  1. TimeZone vs. TimeZoneInfo in .Net
  2. DateTime vs. DateTimeOffset in .Net

It is available through JupiterMedia and can be viewed at http://www.internet.com/video/. Just look for the "Developer Video" titled "Date & Times in .Net 3.5".  Direct links are:

http://www.internet.com/video/?bcpid=1431564240&bclid=1433966034&bctid=1757572900
http://link.brightcove.com/services/link/bcpid1431564240/bclid1433966034/bctid1757572900

Posted in .Net, Webcast | 1 Comment »

Changing the default Clock Skew in WCF

Posted by Dan Rigsby on 26th August 2008

It is possible that if you use a WCF binding that has a security binding element, you may encounter the the following exception:

The security timestamp is invalid because its creation time (‘8/262008 1:45:51 PM’) is in the future. Current time is ‘8/26/2006 1:40:01 PM’ and allowed clock skew is ‘00:05:00′.

The exception is of type TimeStampHasCreationTimeInFuture which is defined as: “The security timestamp is invalid because its creation time is in the future. Current time is specified and allowed clock skew is specified.”

This occurs when the difference of the client/server clocks is larger than the allowed value (the default is 5 minutes).  There two possible solutions to this issue:

  1. Set the clocks on the client and server such that they are more in sync.  (You can use “net time” to help you accomplish this.)
  2. Increase the allows clock skew time on the binding.

Option one is by far the easiest, but isn’t always possible depending on your network nor is to the most bulletproof since other clients could have the same issue. Option two isn’t as easy as it sounds though.  There is no setting you can change on your current bindings to set the max clock skew.  Instead, you need to resort to a custom binding.

Here is an example of a custom binding created in a configuration file with the max clock skew set to 15 minutes instead of the default 5 minutes:

<system.serviceModel>
    <services>
        <service name="MyService" behaviorConfiguration="MyBehavior">
            <endpoint address ="" binding="MyCustomBinding" contract="IMyService" />
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="MyBehavior">
                <serviceMetadata httpGetEnabled="True"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <bindings>
        <customBinding>
            <binding name="MyCustomBinding">
                <security>
                    <localClientSettings maxClockSkew="00:15:00" />
                    <localServiceSettings maxClockSkew="00:15:00" />
                    <secureConversationBootstrap />
                </security>
                <textMessageEncoding />
                <httpTransport />
            </binding>
        </customBinding>
    </bindings>
</system.serviceModel>
 
You can do the same in code.  However you can build a custom binding by extending any existing binding.
 
// Create custom binding by extending any existing binding.
System.ServiceModel.Channels.CustomBinding myCustomBinding =
    new System.ServiceModel.Channels.CustomBinding(binding);

// Find the security binding element
System.ServiceModel.Channels.SecurityBindingElement security =
    myCustomBinding.Elements.Find<SecurityBindingElement>();

// Change the clock skew for service and client
if (security != null)
{
    security.LocalServiceSettings.MaxClockSkew = TimeSpan.FromMinutes(15);
    security.LocalClientSettings.MaxClockSkew = TimeSpan.FromMinutes(15);
}
DotNetKicks Image

Posted in Wcf | No Comments »

Remotely Log Off Remote Desktop Users

Posted by Dan Rigsby on 26th August 2008

I frequently use Remote Desktop to access various PCs here at work and nothing annoys me more than seeing this message box:

RemoteDesktopExceeed

This is caused when “The terminal server has exceeded the maximum number of allowed connections.”, right?  Basically, this happens because Windows by default only allows two simultaneous terminal services connections to the same machine.  If you see this message, then there is already that number of people logged in, and you cannot connect until one of the sessions logs off.

Usually what happens is that people don’t explicitly log out of machines when they disconnect from remote desktop which causes their “rogue” sessions to remain active.  You could just nicely ask everyone if they would please “log off” before disconnecting their sessions, but is there something else we can do?

To perform the commands I am about to show you, you need to be an administrator on the target machine.  If you aren’t you can’t perform these commands.  However, in most development and test environments, hopefully this won’t be an issue.

How to query for users on a machine

First, how can we query to find out what users have a session on a remote machine?  Windows provides the qwinsta.exe command which we can use to query for the sessions that are running  The format is as follows:

qwinsta /server:<serverName>
 

Here is an example running this command against one of my local machines.  Notice it shows the username, state, and the ID of the session.

cmd3

You can also use quser.exe:

quser /server:<serverName>
 
Here is the same example above but notice it also when they logged in and how long they were idle.

cmd1

How to log a user off of a machine

Now that we know what users are on a machine, how can we force one to disconnect? Again, there is a handy little command called logoff.exe that we can use to force a user to log off of a machine based off of their session ID.  The format is as follows:

logoff <sessionId> /server:<serverName>
 

Here is an example running this command against one of my local machines.  Notice that I used the session ID that I found from the quser.exe command above.

cmd2

Warning: If you remotely log off a user, their log session goes away which could mean that the unsaved data is lost, or if the user is in the middle of an activity, they may come down to your office to chew you out.

kick it on DotNetKicks.com

Posted in Tips, Windows | 15 Comments »

TimeZone vs. TimeZoneInfo in .Net

Posted by Dan Rigsby on 24th August 2008

Working with Dates and Times in .Net 3.5 Series:
Part 1: DateTime vs. DateTimeOffset in .Net
Part 2: TimeZone vs. TimeZoneInfo in .Net

This is Part 2 in a series on working with Dates and Times in .Net 3.5.  You might want to read Part 1: DateTime vs. DateTimeOffset in .Net in WCF before continuing on with this post.

MoonKnt_12The TimeZone data type was introduced in .Net 1.0 as a mechanism for retrieving information about the current time zone, and to convert times from local time to Coordinated Universal Time (UTC) or vice versa.  The down side is that you cannot use this to represent any other time zone other than the local zone.  It also can’t be used to convert one date time to another zone.  This is a pretty sever limitation and something that .Net has been lacking for some time.

In .Net 3.5, Microsoft finally introduced a replacement for TimeZone.  The TimeZoneInfo class fills in all of the gaps where TimeZone left off.  You can represent any time zone and perform various calculations.  Many people have yet to hear of this class, but it is crucial if you are working with applications that need to perform calculations on dates and times which may originate from differet time zones. The major functions of this class include the ability to:

  • Retrieving a time zone that is already defined by the operating system. This can be retrieved by ID or the current local time zone.
  • Converting times between different time zones.
  • Enumerating the time zones that are available on a system.
  • Find all time zones a DateTime or DateTimeOffset can represent.
  • Creating a new time zone that is not already defined by the operating system.
  • Serializing a time zone for later retrieval.

View the complete list of members here: http://msdn.microsoft.com/en-us/library/system.timezoneinfo_members.aspx

Use this class to work with any time zone that is predefined on a system, to create new time zones, and to easily convert dates and times from one time zone to another. The TimeZoneInfo class replaces the TimeZone class in every way.  For all new development, ignore the TimeZone class and move straight to TimeZoneInfo.  The TimeZone class should probably have been marked as “Obsolete”.

How TimeZone class works

TimeZone timeZone = System.TimeZone.CurrentTimeZone;
Console.WriteLine(timeZone.StandardName);
 
With the TimeZone class you could pull the current time zone with the static CurrentTimeZone static property.  The TimeZone class has no constructors and fairly limited use.  You can convert dates and times from the local zone to UTC, but you have no access to other time zones.

How to retrieve a time zone with TimeZoneInfo

TimeZoneInfo hwZone =
    TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time");
TimeZoneInfo info = TimeZoneInfo.Local;
 
The TimeZoneInfo class allows you to access the local time zone with the Local static property.  This is similar to the TimeZone class.  However, TimeZoneInfo also allows you to reference any time zone with the FindSystemTimeZoneById static method. This method takes in a string which represents the Id for the time zone. Once you have this time zone, you can work with methods on the object to perform a variety of conversions.
 
A TimeZoneNotFoundException is thrown if the time zone ID could not be found on the local system.

How to convert times between different time zones with TimeZoneInfo

The TimeZoneInfo provides a few conversion methods to allow conversions between different time zones.  The most useful of which is the ConvertTime method.  With this, you can pass in a date/time and the time zone in which you want to convert it into.  If you are using DateTimeOffset, then when you compare the two date/time values, they are equivalent since they both represent the same time, just in different time zones.

DateTimeOffset nowDateTime = DateTimeOffset.Now;
DateTimeOffset newDateTime = TimeZoneInfo.ConvertTime(
    nowDateTime,
    TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time"));
Console.WriteLine("Now: {0}", nowDateTime);
Console.WriteLine("Now in Hawaii: {0}", newDateTime);
 
timezoneinfo1 

How to enumerate through all time zones on the computer with TimeZoneInfo

The GetSystemTimeZones method of the TimeZoneInfo class returns a ReadOnlyCollection of all of the time zones that the current system knows about.

ReadOnlyCollection<TimeZoneInfo> timeZones = TimeZoneInfo.GetSystemTimeZones();
Console.WriteLine("All time zones:");
foreach (TimeZoneInfo timeZoneInfo in timeZones)
{
    Console.WriteLine("   {0}", timeZoneInfo.DisplayName);
}

timezoneinfo2 

How to find all time zones a DateTime or DateTimeOffset can represent with TimeZoneInfome

Most date time offset can represent multiple time zones.  For instance, if a date and time have a –6 hour offset, this could be in the Central Time, Central American, Saskatchewan, or Guadalajara.  With the TimeZoneInfo class, you can easily find all of the time zones that the date and time could represent by simply interating over all of the time zones on the system and comparing their offset to the offset stored in the DateTimeOffset object:

DateTimeOffset current = DateTimeOffset.Now;
ReadOnlyCollection<TimeZoneInfo> timeZones = TimeZoneInfo.GetSystemTimeZones();
Console.WriteLine("You might be in the following time zones:");
foreach (TimeZoneInfo timeZoneInfo in timeZones)
{
    // Compare offset with offset for that date in that time zone
    if (timeZoneInfo.GetUtcOffset(current).Equals(current.Offset))
    {
        Console.WriteLine("   {0}", timeZoneInfo.DisplayName);
    }
}
 
This code outputs all of the following time zones.  DateTimeOffset.Now happens to represent “Eastern Time” in this example.
 
timezoneinfo3 

How to create a new time zone with TimeZoneInfo

The TimeZoneInfo class has no constructors, so it is impossible to new up a new instance.  However, it does provide a static method called CreateCustomTimeZone that allows you to create a new time zone to work with.  This method has a couple of overrides to provide you with everything needed to create a new time zone.  The following creates a new simple time zone called “My Custom Time Zone” which has a –4 hour offset from GMT and observes daylight savings time.

TimeZoneInfo info = TimeZoneInfo.CreateCustomTimeZone(
    "My Custom Time Zone",
    new TimeSpan(-4, 0, 0),
    "My Custom Time Zone",
    "My Custom Time Zone",
    "My Custom Time Zone",
    new TimeZoneInfo.AdjustmentRule[] { },
    false);

How to serialize a time zone with TimeZoneInfo

One of the unique features of the TimeZoneInfo class is that it has a native method to serialize the time zone to a string.  The ToSerializedString method is unlike other serialization methods in that it doesn’t serialize to xml by default, but instead to a semicolon delimited list.  This serialized string can be stored to disk or some other location for later retrieval.

TimeZoneInfo info = TimeZoneInfo.Local;
string serialized = info.ToSerializedString();
 
This code produces the following output:

Eastern Standard Time;-300;(GMT-05:00) Eastern Time (US & Canada);Eastern Standard Time;Eastern Daylight Time;[01:01:0001;12:31:2006;60;[0;02:00:00;4;1;0;];[0;02:00:00;10;5;0;];][01:01:2007;12:31:9999;60;[0;02:00:00;3;2;0;];[0;02:00:00;11;1;0;];];

To deserialize the string back into a TimeZoneInfo class, you can use the FromSerializedString static method to create a new TimeZoneInfo object.

TimeZoneInfo info2 = TimeZoneInfo.FromSerializedString(serialized);
DotNetKicks Image

Posted in .Net, C# | 10 Comments »

Indispensable Wordpress Plugins

Posted by Dan Rigsby on 23rd August 2008

wordpress I often get asked what I use for a blog engine.  I use Wordpress.org on a hosted server.  I use Wordpress primarily for its community and huge network of plugins and tools.  I would prefer to use a .Net based blog engine of a PHP one, but its hard to beat the stability and extensibility that the community provides to Wordpress right now.  One day I may move to another engine.

Knowing that I use Wordpress inevitably leads to the question of what plugins I use.  Here is a list of the plugins for Wordpress that I view as “Indispensable” right now.  If you notice, even this list of plugins is generated by another plugin called WP-PluginsUsed. I keep this list updated on my about page as well, but it is useful enough to also warrant a full blog post.

If anyone ever has any questions about my blog or what I use, feel free to ask!

Indispensable Plugins

Akismet 2.2.7  Akismet 2.2.7
» Matt Mullenweg (url)
Akismet checks your comments against the Akismet web service to see if they look like spam or not. You need a WordPress.com API key to use it. You can review the spam it catches under “Comments.” To show off your Akismet stats just put <?php akismet_counter(); ?> in your template. See also: WP Stats plugin.

BackUpWordPress 0.4.5  BackUpWordPress 0.4.5
» Roland Rust (url)
Manage WordPress Backups. Beta Release. Please help testing and give me feedback under the comments section of the Plugin page. Backup DB, Files & Folders, use .tar.gz, .zip, Exclude List, etc.

Broken Link Checker 0.7.4  Broken Link Checker 0.7.4
» Janis Elsts (url)
Checks your posts for broken links and missing images and notifies you on the dashboard if any are found.

Category Cloud Widget 1.7  Category Cloud Widget 1.7
» Lee Kelleher (url)
Adds a sidebar widget to display the categories as a tag cloud.

Collapsible Archive Widget 2.3.1  Collapsible Archive Widget 2.3.1
» Ady Romantika (url)
Display Collapsible Archive in yous sidebar to save space.

FeedBurner FeedSmith 2.3.1  FeedBurner FeedSmith 2.3.1
» FeedBurner (url)
Originally authored by Steve Smith, this plugin detects all ways to access your original WordPress feeds and redirects them to your FeedBurner feed so you can track every possible subscriber.

Google Analyticator 6.0.2  Google Analyticator 6.0.2
» Ronald Heft (url)
Adds the necessary JavaScript code to enable Google’s Analytics. After enabling this plugin visit the settings page and enter your Google Analytics’ UID and enable logging.

Google XML Sitemaps 3.2.2  Google XML Sitemaps 3.2.2
» Arne Brachhold (url)
This plugin will generate a special XML sitemap which will help search engines like Google, Yahoo, Bing and Ask.com to better index your blog.

OpenID 3.3.2  OpenID 3.3.2
» DiSo Development Team (url)
Allows the use of OpenID for account registration, authentication, and commenting. Also includes an OpenID provider which can turn WordPress author URLs into OpenIDs.

Search Unleashed 1.0.6  Search Unleashed 1.0.6
» John Godley (url)
Advanced search engine that provides full text searching across posts, pages, comments, titles, and URLs. Searches take into account any data added by other plugins, and all search results are contextually highlighted. You can also highlight incoming searches from popular search engines.

Twitter Tools 2.0  Twitter Tools 2.0
» Alex King (url)
A complete integration between your WordPress blog and Twitter. Bring your tweets into your blog and pass your blog posts to Twitter. Show your tweets in your sidebar, and post tweets from your WordPress admin.

Wordpress Automatic Upgrade 1.2.5  Wordpress Automatic Upgrade 1.2.5
» Keith Dsouza (url)
Wordpress Automatic Upgrade allows a user to automatically upgrade the wordpress installation to the latest one provided by wordpress.org using the 5 steps provided in the wordpress upgrade instructions. Go to Wordpress Automatic Upgrade to upgrade your installation Thanks to Ronald Huereca for making the plugin run in automatic mode.

WordPress Mobile Edition 3.1  WordPress Mobile Edition 3.1
» Crowd Favorite (url)
Show your mobile visitors a site presentation designed just for them. Rich experience for iPhone, Android, etc. and clean simple formatting for less capable mobile browsers. Cache-friendly with a Carrington-based theme, and progressive enhancement for advanced mobile browsers.

WP-DBManager 2.50  WP-DBManager 2.50
» Lester 'GaMerZ' Chan (url)
Manages your Wordpress database. Allows you to optimize database, repair database, backup database, restore database, delete backup database , drop/empty tables and run selected queries. Supports automatic scheduling of backing up and optimizing of database.

WP-PageNavi 2.50  WP-PageNavi 2.50
» Lester 'GaMerZ' Chan (url)
Adds a more advanced paging navigation to your WordPress blog.

WP-PluginsUsed 1.50  WP-PluginsUsed 1.50
» Lester 'GaMerZ' Chan (url)
Display WordPress plugins that you currently have (both active and inactive) onto a post/page.

WP-Print 2.50  WP-Print 2.50
» Lester 'GaMerZ' Chan (url)
Displays a printable version of your WordPress blog’s post/page.

WPtouch iPhone Theme 1.9.7.4  WPtouch iPhone Theme 1.9.7.4
» Dale Mugford & Duane Storey (BraveNewCode) (url)
A plugin which formats your site with a mobile theme for the Apple iPhone / iPod touch, Google Android and other touch-based smartphones.

DotNetKicks Image

Posted in Wordpress | 6 Comments »

DateTime vs. DateTimeOffset in .Net

Posted by Dan Rigsby on 23rd August 2008

Working with Dates and Times in .Net 3.5 Series:
Part 1: DateTime vs. DateTimeOffset in .Net
Part 2: TimeZone vs. TimeZoneInfo in .Net

MoonKnt_12 The DateTime data type has been around since .Net 1.0 and suited us well for a long time.  It simply defines a date and a time together and offers methods for working with these constructs. It is a struct and hence can’t be set to null.  This caused some people some problems over the years.  Especially when modeling a DateTime from the database, since in most databases like SQL Server, the datetime field can be null.  So, usually a null DateTime would be set to DateTime.MinValue.  However, this wasn’t the most optimal solution.

In .Net 2.0 nullable types were introduced.  Now, we could have a null DateTime by simply defining the field as  System.Nullable<DateTime> (or DateTime?) instead of the standard DateTime.  This allowed us to set the field to null, and pull the value using the Value property of the field.

In .Net 3.5 an entirely new date/time field was added called DateTimeOffset.  This data extends the DateTime to add in the concept of a timezone offset.  It is still a struct, so you need to use System.Nullable<DateTimeOffest> if you want to be able to have a null value. A DateTimeOffset value is not tied to a particular time zone, but can originate from any of a variety of time zones.  For example, there are can multiple timezones that represent the same offset such as UTC –6:00 which can be Central Time, Central American, Saskatchewan, or Guadalajara.  So you don’t know the timezone that the datetime represents, but you do know the offset.  This is all you need to perform comparisons to other DateTimeOffsets.

180px-PrimemeridianThe offset value represents the time difference between the current time and Greenwich Mean Time (GMT) this is known as Coordinated Universal Time (UTC).  GMT historically is the time when the sun crosses the Prime Meridian line which is located a 0 Longitude. IT is measured from the Greenwich Meridian Line at the Royal Observatory in Greenwich, England.  This is the place from where all time zones are measured. Even the atomic clocks of the world are adjusted by leap seconds to maintain synchronicity with GMT.

So why is UTC so important to software developers?  This may be an obvious answer to most, but if you haven’t been exposed to this, it’s because many applications need to be globalized and may be run in different timezones.  If someone enters in a date and time, is that relative to their timezone or the timezone the server is sitting on.  This can be vastly different and can really cause problems in your application.  Comparing all dates and times to the relative time of GMT allows applications to understand what the date and time actually represent.

What does DateTime and DateTimeOffest look like

Console.WriteLine(DateTime.Now);
Console.WriteLine(DateTimeOffset.Now);
 
datetime1
 
This print out shows the basic difference in the two types.  The DateTime shows the Date and Time, while the DateTimeOffset shows the Date, Time, and offset.  This offset represents the difference from GMT.  In this case 4 hours behind GMT.

How to convert from DateTime to DateTimeOffset

DateTime d1 = DateTime.Now;
DateTimeOffset o1 = new DateTimeOffset(d1);
DateTimeOffset of1 = new DateTimeOffset(d1, new TimeSpan(-5, 0, 0));
 
To convert a DateTime into a DateTimeOffset, you just need to pass the DateTime value into one of the constructors of the DateTimeOffset.  You could just pass the DateTime in (as in o1 above), or you can also pass in the DateTime and an offset (as in of1 above).  If you don’t supply an offset, then GMT is assumed.

How to convert from DateTimeOffest to DateTime

DateTimeOffset o2 = DateTimeOffset.Now;
DateTime d2 = o2.DateTime;
 
Converting a DateTimeOffset to a DateTime is easy.  Since the DateTimeOffset value contains all of the data of a DateTime field and more, there is a simple DateTime property on the DateTimeOffset struct that returns a DateTime representation of the value.

How to manually set DateTime and DateTimeOffset

DateTime dt1 = new DateTime(2008, 8, 22, 1, 0, 0);
DateTimeOffset do1 = new DateTimeOffset(2008, 8, 22, 1, 0, 0, new TimeSpan(-5, 0, 0));
Console.WriteLine(dt1);
Console.WriteLine(do1);
 
datetime2 
 
Manually setting a DateTimeOffset is very similar to setting the value of a DateTime.  The only difference is that you can also pass in a TimeSpan as the last argument that represents the GMT offset.

Arithmetic with Datetime and DateTimeOffest

DateTime dateTime1 = DateTime.Now;
DateTime dateTime2 = DateTime.UtcNow;
Console.WriteLine("{0} - {1} =", dateTime1, dateTime2);
Console.WriteLine(dateTime1 - dateTime2);

Console.WriteLine();

DateTimeOffset offset1 = DateTimeOffset.Now;
DateTimeOffset offset2 = DateTimeOffset.UtcNow;
Console.WriteLine("{0} - {1} =", offset1, offset2);
Console.WriteLine(offset1 - offset2);
 

datetime3

With this example we can see that the difference between Now and UtcNow is 0.  This means that the DateTimeOffset sees the UTC version of the time and the local version of the time as equal.  But what about something more complicated? Are 12 PM EST and 9AM PST equal?

DateTimeOffset ao1 = new DateTimeOffset(2008, 8, 22, 12, 0, 0, new TimeSpan(-5, 0, 0));
DateTimeOffset ao2 = new DateTimeOffset(2008, 8, 22, 9, 0, 0, new TimeSpan(-8, 0, 0));
Console.WriteLine(ao1 == ao2);
 
This code creates 2 times.  One is 12 PM August, 22 2008 and the second is 9 AM August, 22 2008.  However, the offsets for each are set for Eastern Standard time and Pacific Standard time respectively.  If we compare these two values, are they equal?  If you guessed “Yes”, then you are right.  The Equals() method of DateTimeOffset knows now to compare against the offsets.  This is incredibly useful when comparing times cared in different time zones.

When to use DateTime or DateTimeOffest

Use DateTimeOffest structure to work with dates and times whose offset (or difference) from UTC is known or when calculations need to be performed on dates that may be from different timezones. The DateTimeOffset value is also more portable from one computer to another than a DateTime value.  DateTimeOffset doesn’t necessarily replace DateTime though.  DateTime is still useful to represent a single date or time or when the timezone information is unknown or not important.  However most developers should explore using DateTimeOffest more in general use especially in enterprise level systems.

DateTime may also be the best type to represent a DateTime from the database since the DateTime fields in most databases don’t store timezone information.  In SQL Server 2008 a DateTimeOffset structure was introduced to the database as well.  This type is very comparable to the DateTimeOffset field in .Net.  So a good rule of thumb may be to use the corresponding types when mapping between SQL Server 2008 and .Net 3.5.

 

Update: Nicholas Allen posted a reminder of how to deal with DateTimeOffest fields when working with svcutil.exe: http://blogs.msdn.com/drnick/archive/2008/09/04/getting-better-time-formats.aspx

DotNetKicks Image

Posted in .Net, C# | 8 Comments »

MSDN Forums Milestone: Moderator

Posted by Dan Rigsby on 22nd August 2008

msdn-thumbMy many months of contributions to Microsoft’s MSDN message forums haven’t gone unnoticed.  It was less than a week ago that I finally achieved 5/5 stars, and yesterday I received an email thanking me for my work and asking if I would like to take on a more involved role a forum moderator.  I accepted the honor and promised to take this role seriously.  I help out on the forums because I enjoying helping others learn and learning myself in the process.  I hope that I can keep this up even more a moderator.

Moderators are granted the power to delete, edit, and merge posts.  Moderators can also mark posts as “Answers” which is probably the most important role.  Many people who ask questions, don’t mark the answers that are made.  Marking a post as answered not only gives credit to the answerer, but also causes these posts to show up with a higher rating in search engines.  This can help others who are searching the Internet for their own questions.

 msdnmod

Please visit the MSDN Forums (or the new Forums) if you have questions about Microsoft products.  There are many different forum topics and thousands of people who can help and share insights.  While you are visiting, feel free to help out others as well.  As a  community site dedicated to helping everyone learn, it needs your involvement and support.  If you want to get more involved in the community, are seeking to test your skills, or just want to help others, this is the place for you.

Posted in Community, MSDN Forums | 5 Comments »

WcfTestClient Change in Visual Studio 2008 SP1

Posted by Dan Rigsby on 21st August 2008

In the previous version of the WcfTestClient, every call to the server would result in a new instance of the proxy being created.  So, if you wanted to do any testing based on sessions, you had to use another tool.  In SP1, Microsoft has updated the WcfTestClient with a check box named “Start a new proxy” which defines whether or not to create a new proxy client with that call.  The default value is to reuse the same proxy instance.

wcftestclient2

Posted in Visual Studio, Wcf | 2 Comments »

ObservableServiceHost – An InstanceContext creation aware WCF ServiceHost

Posted by Dan Rigsby on 20th August 2008

On the MSDN Forums for WCF recently, an enhancement request was proposed to add an event to the ServiceHost class that is fired when a new instance of the service is created.  The proposed event would look something like this:
 
ServiceHost host = new ServiceHost(typeof(MyService));
host.Open();
host.InstanceCreated += new EventHandler<InstanceEventArgs>(host_InstanceCreated);
 
It was decided that this may not be the best enhancement request since this could be done today with the extension mechanisms built into WCF.  The usefulness of the event is also dependent on the type of InstanceContextMode used:
  1. PerCall: Every call made to the endpoints would create a new service instance.  This could be useful.
  2. PerSession: Every new client connection would create a new service instance for the life of the client’s session. This could be very useful.
  3. Single: A service instance is created during the first call.  This is fairly useless since it is called when the single instance of the service starts, but not again.

However, I accepted the challenge to come up with an implementation of this extension.  What I came up with is called ObservableServiceHost.  This is a custom ServiceHost that you can use instead of the default System.ServiceModel.ServiceHost.  The solution requires only 4 files:

1. InstanceEventArgs

A simple EventArgs class is needed as a container for the InstanceContext.

public class InstanceEventArgs : EventArgs
{
    public InstanceContext InstanceContext
    {
        get;
        set;
    }

    public InstanceEventArgs()
    {
    }

    public InstanceEventArgs(
        InstanceContext instanceContext)
    {
        InstanceContext = instanceContext;
    }
}
 

2. ObservableServiceHost

ObservableServiceHost extends the functionality of a ServiceHost.  This class consists of the following:

  • A new event called InstanceCreated which uses the InstanceEventArgs.
  • Re-implemented constructors of the base ServiceHost class.
  • When the ServiceHost is Opened, a custom IEndpointBehavior is added to each of the endpoints used at the time the service is opened.  Endpoints which implement IMetadataExchange are be ignored though since the event doesn’t need to be fired a new metadata instance is created. (You could potentially modify this to add a different behaviors for different service interfaces.)
public class ObservableServiceHost : ServiceHost
{
    public event EventHandler<InstanceEventArgs> InstanceCreated;

    protected internal virtual void OnInstanceCreated(
        InstanceContext instanceContext)
    {
        EventHandler<InstanceEventArgs> handler = InstanceCreated;
        if (handler != null)
        {
            handler(this, new InstanceEventArgs(instanceContext));
        }
    }

    public ObservableServiceHost(
        object singletonInstance,
        params Uri[] baseAddresses) : base(singletonInstance, baseAddresses)
    {
    }

    public ObservableServiceHost(
        Type serviceType,
        params Uri[] baseAddresses) : base(serviceType, baseAddresses)
    {
    }

    protected override void OnOpening()
    {
        AddInstanceContextInitializers();

        base.OnOpening();
    }

    private void AddInstanceContextInitializers()
    {
        foreach (ServiceEndpoint endpoint in this.Description.Endpoints)
        {
            if (endpoint.Contract.ContractType != typeof(IMetadataExchange))
            {
                endpoint.Behaviors.Add(new InstanceCreationEndpointBehavior(this));
            }
        }
    }
}

3. InstanceCreationInitializer

This is a basic implementation of IInstanceContextInitializer which can be used to inspect the InstanceContext when an instance is created.  This class consists of the following:

public class InstanceCreationInitializer : IInstanceContextInitializer
{
    private ObservableServiceHost m_ObservableServiceHost;

    #region IInstanceContextInitializer Members
    public void Initialize(
        InstanceContext instanceContext,
        Message message)
    {
        if (m_ObservableServiceHost != null)
        {
            m_ObservableServiceHost.OnInstanceCreated(instanceContext);
        }
    }
    #endregion IInstanceContextInitializer Member

    public InstanceCreationInitializer(
        ObservableServiceHost observableServiceHost)
    {
        m_ObservableServiceHost = observableServiceHost;
    }
}

4. InstanceCreationEndpointBehavior

This class implements IEndpointBehavior which is used to extend the runtime behavior of an endpoint and add our InstanceCreationInitializer to the endpoint dispatcher.  It is this behavior that we add to each of the endpoints when the ObservableServiceHost opens.

This class consists of the following:

  • A constructor that takes in a reference to the ObservableServiceHost and creates an instance of the InstanceCreationInitializer.
  • An implementation of IEndpointBehavior.ApplyDispatchBehavior which adds our InstanceCreationInitializer to the endpoint dispatchers InstanceContextInitializers collection.  This will cause our InstanceCreationInitializer to be run when a new instance is created.  The InstanceCreationInitializer  in turn calls our InstanceCreated event on the ObservableServiceHost.
public class InstanceCreationEndpointBehavior : IEndpointBehavior
{
    private InstanceCreationInitializer m_InstanceCreationInitializer;

    #region IEndpointBehavior Members

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        endpointDispatcher.DispatchRuntime.InstanceContextInitializers.Add(
            m_InstanceCreationInitializer);
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
    #endregion IEndpointBehavior Members

    public InstanceCreationEndpointBehavior(
        ObservableServiceHost observableServiceHost)
    {
        m_InstanceCreationInitializer = new InstanceCreationInitializer(observableServiceHost);
    }

}

Example Service

Included in the code for this article is an example of how to use this library.  You can take any new or existing service and use it with the ObservableServiceHost, then just attach to the InstanceCreated event:

static class Program
{
    static void Main(string[] args)
    {
        ObservableServiceHost serviceHost = new ObservableServiceHost(
            typeof(MyService));
        serviceHost.Open();
        serviceHost.InstanceCreated += new EventHandler<InstanceEventArgs>(serviceHost_InstanceCreated);

        Console.WriteLine("Press any key to exit application...");
        Console.WriteLine();
        Console.ReadLine();

        serviceHost.Close();
    }

    static void serviceHost_InstanceCreated(object sender, InstanceEventArgs e)
    {
        Console.WriteLine("New InstanceContext created");
    }
}
 
For this sample, we are just outputting a string every time a new IntanceContext is created (You could have this do more meaningful work). Now use the WcfTestClient or any other custom client to hit the endpoint (http://localhost:8080/MyService/).  When operations are run on the service, the “New InstanceContext created” message is written to the console:

TestServer

You can play around with the InstanceContextMode on the Service to see what happens when you use it with PerCall, PerSession, or Single.  The line of code to look for is:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]

 

I hope others find this class useful or at least have learned more about the extensibility that WCF has to offer. You can download the complete library and sample server here: http://www.danrigsby.com/Files/Rigsby.ServiceHostCreation.zip

kick it on DotNetKicks.com

Posted in Wcf | 4 Comments »