Quite often we run into situations where we need to measure the elapsed time of a method/operation, and there are number of ways to do it. The simplest way to do is by using a Stopwatch. This class is available under the namespace System.Diagnostics.
To show you a demo, I have used a simple app which calculates the time taken to load a website on your local machine.
namespace Nish.Stopwatch
{
class Program {
static void Main(
string[] args)
{
Console.WriteLine(
"WebAddress> ");
Console.WriteLine(
"Your website took about " + LoadWebsite(
Console.ReadLine()).Seconds +
" seconds to load on your machine");
Console.ReadLine();
}
/// <summary>
/// Gets the load time of a website
/// </summary>
/// <param name="websitePath">Path in the format: e.g. http://nnish.com </param>
/// <returns>Time taken</returns>
private static TimeSpan LoadWebsite(string websitePath)
{
System.Diagnostics.Stopwatch stpWatch = new System.Diagnostics.Stopwatch();
stpWatch.Start();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(websitePath);
// execute the request
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Read the data in the stream
StreamReader streamReader = new StreamReader(response.GetResponseStream());
// s – will have your html content, I am not using this for now
string s = streamReader.ReadToEnd();
stpWatch.Stop();
return stpWatch.Elapsed;
}
}
}
Time took for my website to load:
Look at the time Google took:
And now this was out of curiosity:
Please note: The load time depends on various factors like network speed, server location, page content etc. So this data should not be treated as accurate. The idea of having this example is to show the usage of Stopwatch and not to determine the speed of the website.
Method Stopwatch.Start() starts the timer, and ticks in parallel until the Stopwatch.Stop() is executed. The start method does not start the elapsed time at 0, if executed again. To set the elapsed time to 0 use either Stopwatch.Restart() or call Stopwatch.Reset() before the next start(). So understand that “A Stopwatch instance calculates and retains the cumulative elapsed time across multiple time intervals, until the instance is reset/restarted.” – MSDN. To start a fresh timer use Stopwatch stopwatch = Stopwatch.StartNew() which is a static method.
This comes very handy when you use this for all your performance monitoring or benchmarking on/the your operations.
Cheers!
Today afternoon I was on a mission to complete a long pending personal project and as part of it I was developing a windows service which extended the support of starting and stopping the service from a console window. After the completion it was time for me to start testing that out and then this weird thing happened. Whenever the system encountered a Console.ReadLine(), it gave me a strange error: “Not enough storage is available to process this command.” But executing a Console.WriteLine() was not an issue. After playing around with it for a while I figured out the project I had selected was Windows Service and hence it’s output type was Windows Application. Changing the project type to a Console application did the trick. Hopefully this helps someone.
Cheers!
A very familiar way of implementing the frequently changing value in an application is by storing them in a configuration file’s <appSettings> section. When the project is big, storing too many values in application settings is not a suggested approach, as this can lead to confusions and many other integration problems. Many at times we have seen when the code is moved from a development environment to a production environment there is a mismatch in the the configuration or we loose out on some important values. These issues can be eliminated by simply using a custom configuration section. A project constitutes of many modules and each module will have configuration values specific to them. So it will be a good idea to group them to a single section, and every module’s configuration values will reside in their respective section. This way by just looking at the configuration one can figure out which value relates to what module. It is also suggested to have a common section so that these values can be accessed by all the modules and will reduce duplication of values.
Going forward you will learn about creating custom configuration section, the corresponding value holder class, and properties to access them through out the application. I will make the demo simple to a console application, so that it is easy to understand.
Start a new Console application and add an application configuration file to it. Also reference System.Configuration.dll.
What’s in the Configuration?
- <?xml version=“1.0“ encoding=“utf-8“ ?>
- <configuration>
- <configSections>
- <section name=“MyConfiguration“ type=“ConfigurationC.MyConfiguration, ConfigurationC“/>
- </configSections>
- <!– Configuration settings for MyConfiguration Starts –>
- <MyConfiguration
- To=“support@nnish.com“
- From=“sales@nnish.com“>
- <Messages>
- <Message Name=“Email“ Value=“email“/>
- <Message Name=“Sms“ Value=“sms“/>
- <Message Name=“Tweet“ Value=“tweet“ />
- </Messages>
- </MyConfiguration>
- <!– Configuration settings for MyConfiguration Ends –>
- </configuration>
Lets break this into bits and pieces. Notice the <configSections> element –this is where you register your custom configuration. To add a custom configuration – add an element <section name=”” type=””/>.
- name – represents the name of the custom configuration
- type – used as <namespace.Type>, <AssemblyName> (Type is the corresponding class which inherits ConfigurationSection)
And the <MyConfiguration>element is nothing but the custom configuration section which contains custom values stored. I will explain multiple ways of storing in the config files and accessing them from the application. In the config, I store some values as the attribute of the main element, the main element has the sub element <Messages> and that in turn has the collection of <Messages> having attributes “Name” and “Value”. This can be easily related to <add> element in the <appSettings>.
What’s in the Code?
Now let us go ahead and build the classes for accessing these values in the application.
Remember these:
- There should be a class in the application representing each element (including the sub elements) in the configuration file.
- Class holding the custom Configuration Section should inherit from CustomSection
- public class MyConfiguration : ConfigurationSection
- The attributes/elements can be represented as a property which is of type ConfigurationProperty in the parent class.
- Class representing an element collection should inherit from ConfigurationElementCollection
- public class MessageCollection : ConfigurationElementCollection
- Class representing an element should inherit from ConfigurationElement
- public class MessageElement : ConfigurationElement
Since <Message> is the last child element, write the corresponding class for it first, and then <Messages> which is its parent and it holds the collection of <Messages> and finally the class for <MyConfiguration> which has attributes represented as properties in itself.
Element: <Message> – Class: MessageElement
- using System.Configuration;
-
- namespace ConfigurationC
- {
- /// <summary>
- /// Class holds the <Message> element
- /// </summary>
- public class MessageElement : ConfigurationElement
- {
- // Holds the Name attribute of the Message
- private static readonly ConfigurationProperty messageName =
- new ConfigurationProperty(“Name”, typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired);
-
- // Holds the Value attribute value of Message.
- private static readonly ConfigurationProperty messageValue =
- new ConfigurationProperty(“Value”, typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired);
-
- public MessageElement()
- {
- base.Properties.Add(messageName);
- base.Properties.Add(messageValue);
- }
-
- /// <summary>
- /// Name
- /// </summary>
- [ConfigurationProperty("Name", IsRequired = true)]
- public string Name
- {
- get { return (string)this[messageName]; }
- }
-
- /// <summary>
- /// Value
- /// </summary>
- [ConfigurationProperty("Value", IsRequired = true)]
- public string Value
- {
- get { return (string)this[messageValue]; }
- }
- }
- }
-
Explanation:
- <Message> element has attributes “name” and “value” which are represented as ConfigurationProperty and its initialization takes the following parameters
- name: The name of the configuration entity.
- type: The type of the configuration entity.
- defaultValue: The default value of the configuration entity.
- options: One of the System.Configuration.ConfigurationPropertyOptions enumeration values
- In the constructor add these properties to the base class Property Collection
- Expose them as public property
Element: <Messages> – Class: MessageCollection
- using System.Configuration;
-
- namespace ConfigurationC
- {
- [ConfigurationCollection(typeof(MessageElement), AddItemName = "Message",
- CollectionType = ConfigurationElementCollectionType.BasicMap)]
- public class MessageCollection : ConfigurationElementCollection
- {
- protected override ConfigurationElement CreateNewElement()
- {
- return new MessageElement();
- }
-
- protected override object GetElementKey(ConfigurationElement element)
- {
- return ((MessageElement)element).Name;
- }
-
- new public MessageElement this[string name]
- {
- get { return (MessageElement)BaseGet(name); }
- }
- }
- }
-
Explanation:
- MessageCollection class is inherited from the abstract class ConfigurationElementCollection and two of its abstract methods CreateElement() and GetElementKey() needs to be overridden
- CreateElement() creates the new instance of the MessageElement
- GetElementKey() Gets the element key for a Message element (we define Name attribute as the key, so that the value can be retrieved using the name)
- new public MessageElement this[string name] – add this to retrieve the value with the key name. For e.g: ConfigurationManager.AppSettings[“test”];
Element: <MyConfiguration> – Class: MyConfiguration (Putting them all together[ConfigurationSection ])
- using System.Configuration;
-
- namespace ConfigurationC
- {
- public class MyConfiguration : ConfigurationSection
- {
- private static readonly ConfigurationProperty toAttribute =
- new ConfigurationProperty(“To”, typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired);
-
- private static readonly ConfigurationProperty fromAttribute =
- new ConfigurationProperty(“From”, typeof(string), string.Empty, ConfigurationPropertyOptions.IsRequired);
-
- private static readonly ConfigurationProperty messagesElement =
- new ConfigurationProperty(“Messages”, typeof(MessageCollection), null, ConfigurationPropertyOptions.IsRequired);
-
- public MyConfiguration()
- {
- base.Properties.Add(toAttribute);
- base.Properties.Add(fromAttribute);
- base.Properties.Add(messagesElement);
- }
-
- /// <summary>
- /// To
- /// </summary>
- [ConfigurationProperty("To", IsRequired = true)]
- public string To
- {
- get { return (string)this[toAttribute]; }
- }
-
- /// <summary>
- /// From
- /// </summary>
- [ConfigurationProperty("From", IsRequired = true)]
- public string From
- {
- get { return (string)this[fromAttribute]; }
- }
-
- /// <summary>
- /// Messages Collection
- /// </summary>
- [ConfigurationProperty("Messages", IsRequired = true)]
- public MessageCollection Messages
- {
- get { return (MessageCollection)this[messagesElement]; }
- }
- }
- }
-
Explanation:
- Add all the Attributes and Elements as the ConfigurationProperty of corresponding type.
And the Program.cs
- using System;
- using System.Configuration;
-
- namespace ConfigurationC
- {
- public class Program
- {
- public static MyConfiguration MyConfig;
-
- static void Main(string[] args)
- {
- MyConfig = GetConfiguration();
-
- Console.WriteLine(“This program comes with no warranty!”);
- Console.WriteLine(“Values found in the configuration”);
- Console.WriteLine(“To: “ + MyConfig.To);
- Console.WriteLine(“From: “ + MyConfig.From);
- Console.WriteLine(“Message Email: “ + MyConfig.Messages["Email"].Value);
- Console.WriteLine(“Message Sme: “ + MyConfig.Messages["Sms"].Value);
- Console.WriteLine(“Message Tweet: “ + MyConfig.Messages["Tweet"].Value);
- Console.ReadLine();
- }
-
- private static MyConfiguration GetConfiguration()
- {
- return (MyConfiguration)ConfigurationManager.GetSection(“MyConfiguration”);
- }
- }
- }
-
Above code snippet is self explanatory.
I hope I was able to walk you through a step by step process of a developing hello world Custom Configuration section.
Download the code!
Cheers!