Amazon.com Widgets All posts tagged 'C#'

WilliaBlog.Net

I dream in code

About the author

Robert Williams is an internet application developer for the Salem Web Network.
E-mail me Send mail
Code Project Associate Logo
Go Daddy Deal of the Week: 30% off your order at GoDaddy.com! Offer expires 11/6/12

Recent comments

Archive

Authors

Tags

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.


Visual Studio C# Statement Collapsing

Many seasoned developers would argue that if your method is so long, and contains so many nested blocks of code in braces that you need to be able to collapse the sections to make better sense of your code, that you should refactor that code! And of course, they are right. This can be done either by moving sections out to new methods, or perhaps inverting your if statements to reduce nesting. However, lets be honest, when you initially write something, it often starts out as a single really long method and in order to refactor it you still need to identify where each block starts and ends. And of course sometimes you have to work with code other developers wrote. Wouldn't it be nice to be able to collapse a loop, or a try catch block just by clicking on a little minus sign? True you could wrap these sections with regions, but to do that you would have to figure out where the section starts and ends to insert the region statements and by doing that you wouldn't really need them anymore. If you are working in C++ in Visual Studio, you can collapse code blocks, but this functionality is not part of the C# options. Fortunately, there is a Visual Studio 2010 extension you can install to add this functionality to C#.


Posted by Williarob on Friday, April 15, 2011 1:51 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Checking for a Running Instance

Sometimes you may not want a user to launch multiple instances of your program, or you may have a processor or I/O intensive scheduled task that runs every few minutes and you want to make sure that if it is started again before the last instance has finished it simply exits immediately. One way to check to see if your program is already running is to look at the list of running processes:

 

namespace RunningInstance

{

    using System;

    using System.Diagnostics;

    using System.Reflection;

 

    class Program

    {

        static void Main(string[] args)

        {

            if (RunningInstance())

            {

                Console.WriteLine("Another instance of this process was already running, exiting...");

                return;

            }

 

            // ...

        }

 

        static bool RunningInstance()

        {

            Process current = Process.GetCurrentProcess();

            Process[] processes = Process.GetProcessesByName(current.ProcessName);

 

            // Loop through the running processes in with the same name

            foreach (Process p in processes)

            {

                // Ignore the current process

                if (p.Id != current.Id)

                {

                    // Make sure that the process is running from the exe file.

                    if (Assembly.GetExecutingAssembly().Location.Replace("/", @"\") == current.MainModule.FileName)

                    {

                        return true;

                    }

                }

            }

 

            return false;

        }

    }

}

 

However, suppose you have a multi function console application that accepts a dozen different command line arguments to perform different jobs, all of which run as separate scheduled tasks at overlapping intervals. If this is the case, then checking the list of running processes may well find your executable already running, but have no idea which command line argument was used to start it. I tried adding:

 

Console.WriteLine("Instance started with args: '{0}'", p.StartInfo.Arguments);

above the "return true" statement in RunningInstance() but it will not print the command line args used to start it. Lets suppose we add 2 classes to our project. Task1 and Task2. For the sake of simplicity, they both look something like this:

namespace RunningInstance

{

    using System;

    using System.Threading;

 

    public class Task1

    { 

        public void Start()

        {

            Console.WriteLine("Starting Task 1");

        }

    }

}

 

Task 2 is exactly the same, except it prints "Starting Task 2". If we keep our RunningInstance check in place Main() now looks like this:

 

        static void Main(string[] args)

        {

            if (RunningInstance())

            {

                Console.WriteLine("An instance of this application is already running. Exiting.");

                Console.ReadLine();

                return;

            }

 

            if(args.Length < 1)

            {

                Console.WriteLine("Unrecognized Command.");

                return;

            }

 

            switch (args[0])

            {

                case "-task1":

                    var t1 = new Task1();

                    t1.Start();

                    break;

                case "-task2":

                    var t2 = new Task2();

                    t2.Start();

                    break;

                default:

                    Console.WriteLine("Unrecognized Command.");

                    break;

            }

        }

Task 2 will not run, if task 1 is still running, and vice versa. However, suppose the two tasks are completely unrelated. The first is only a minor chore, that simply counts the number of items marked as "queued" in a database table and sends out an email if the number is too high, while task 2 is much lengthier process that FTPs files. We may need both of these tasks to run as scheduled, but not want multiple instances of either task to run at the same time. How can we achive this? We use a Mutex. Mutex is an abbreviation of "Mutual exclusion" and is traditionally used in multi threaded applications to avoid the simultaneous use of a common resource, such as a global variable. After adding a mutex to each task, our final code looks like this:


        static void Main(string[] args)

        { 

            if(args.Length < 1)

            {

                Console.WriteLine("Unrecognized Command.");

                return;

            }

 

            switch (args[0])

            {

                case "-task1":

                    var t1 = new Task1();

                    t1.Start();

                    break;

                case "-task2":

                    var t2 = new Task2();

                    t2.Start();

                    break;

                default:

                    Console.WriteLine("Unrecognized Command.");

                    break;

            }

        }

 

 

namespace RunningInstance

{

    using System;

    using System.Threading;

 

    public class Task1

    {

        /// <summary>Gets the mutex that prevents multiple instances of this code running at once.</summary>

        private static Mutex mutex1;

 

        public void Start()

        {

            bool createdNew;

            mutex1 = new Mutex(true, "RunningInstance.Task1", out createdNew);

            if (!createdNew)

            {

                // Instance already running; exit.

                Console.WriteLine("Exiting: Instance already running");

                return;

            }

 

            Console.WriteLine("Starting Task 1");

        }

    }

}

 

 

namespace RunningInstance

{

    using System;

    using System.Threading;

 

    public class Task2

    {

        /// <summary>Gets the mutex that prevents multiple instances of this code running at once.</summary>

        private static Mutex mutex1;

 

        public void Start()

        {

            bool createdNew;

            mutex1 = new Mutex(true, "RunningInstance.Task2", out createdNew);

            if (!createdNew)

            {

                // Instance already running; exit.

                Console.WriteLine("Exiting: Instance already running");

                return;

            }

            Console.WriteLine("Starting Task 2");

        }

    }

}

 

Each Task has its own Mutex, uniquely named. If the mutex already exists, then that code must already be running, so exit, otherwise, run. Couldn't be simpler. By using this particular overload of the constructor, we don't even need to worry about releasing the mutex at the end of the program.

Categories: C# | CodeProject
Posted by Williarob on Monday, October 04, 2010 5:57 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Random Sample Data Generator

I recently found myself testing a webservice which required simple registration data - Name, Address, City, State, Zip/Postal Code, Phone, Email, etc. Real world testing requires navigating to the appropriate page on our site, selecting a product and completing the registration form. I don't know about you, but I'm pretty lazy when it comes to testing like this. I soon find myself entering the same test data every time, and before long end up typing gibberish like "ASDF" and "QWERTY" to speed things along. Anyone who has tested like this before, will understand the limitations to this approach and how it leads to major bugs slipping through the net. So naturally, I soon found myself writing some unit tests to do the heavy lifting for me. This is an MVC Site, so writing the unit tests was a breeze, but the sample data remained a problem. How could I produce data that would be different every time, but not be gibberish, and really look like real world data?

Well one approach would be to pull real data from our database and recycle it. Such practices, however, can violate a number of data privacy regulations. For example, the 1996 Health Insurance Portability and Accountability Act (HIPAA) mandates companies restrict access to people’s personal health data on a “need to know” basis. Likewise, the Sarbanes-Oxley Act of 2002 requires companies to control access and track changes to systems handling corporate financial information. In addition, over 30 states have passed data breach notification laws requiring companies to notify consumers if their personal information may have been compromised. This includes such things as a person’s name and address, date of birth, social security number, and credit card and bank account numbers. (Mathew Schwartz - The Dangers of Testing with Real Data).

So, the problem then, is how can you get your hands on quality sample data that won't violate privacy regulations? After looking at an Excel Add-in with similar intent, I chose to write a Random Sample Data Generator in C#. The first thing I did was create an XML File full of real first names taken from a list found here. Then I added a list of real last names found on the US Census site. Next I found a list of fake company names and added that. Our database already had a list of countries and states, so I pulled those in too. I created a list of popular street names (Elm, Main, First, Second, Walnut, etc.) and street name suffixes like Road, Street, Blvd., etc. I found a list of common city names somewhere and added that too, as well as name prefixes (Mr., Mrs, Dr., etc) and suffixes (III, Jr., Sr., etc.). Finally, in order to create credible email addresses, I took the fake company name list and turned them into possible domain names. Numeric data such as zip codes and phone numbers is easy to generate, no need to list those unless you must have real zip codes and real area codes. Currently, zip codes and phone numbers are just random digits, but if you wanted to extend it to use real area codes and real zip codes you could add them to the xml file, and write new methods to generate them. Obviously, a little more complex code would be required to pull a matching state, zip code and area code.

All that remained was to write some C# code that could randomly pull data from the lists now stored in my xml file, and here it is:

namespace DataGenerator

{

    using System;

    using System.IO;

    using System.Linq;

    using System.Reflection;

    using System.Text;

    using System.Xml;

    using System.Xml.Linq;

 

    using Extensions;

 

    public static class Generate

    {

        private static readonly XDocument dataDocument;

 

        static Generate()

        {

            if (null == dataDocument)

            {

                using (Stream datafileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("DataGenerator.Data.xml"))

                {

                    if (datafileStream != null)

                    {

                        XmlTextReader xmlReader = new XmlTextReader(datafileStream);

                        dataDocument = XDocument.Load(xmlReader);

                    }

                }

            }

        }

 

        /// <summary>

        /// Random Number Generator

        /// </summary>

        /// <param name="min"></param>

        /// <param name="max"></param>

        /// <example>int myInt = GetRandomInt(5, 1000); // gives in random integer between 5 and 1000</example>

        public static int RandomInt(int min, int max)

        {

            Random rnd = new Random();

            return rnd.Next(min, max);

        }

 

        /// <summary>

        /// Returns a string representing a common name prefix, e.g. Mr., Mrs., Dr., etc.

        /// </summary>

        public static string RandomNamePrefix()

        {

            var randomPrefix = dataDocument.Descendants("data").Descendants("prefixes").Descendants("prefix").ToList().RandomItem(new Random());

            return randomPrefix.Value;

        }

 

        /// <summary>

        /// Returns a string representing a persons last name, randomly selected from actual first names.

        /// </summary>

        public static string RandomFirstName()

        {

            var randomName = dataDocument.Descendants("data").Descendants("names").Descendants("first").ToList().RandomItem(new Random());

            return randomName.Value;

        }

 

        /// <summary>

        /// Returns a string representing a persons last name, randomly selected from actual last names.

        /// </summary>

        public static string RandomLastName()

        {

            var randomName = dataDocument.Descendants("data").Descendants("names").Descendants("last").ToList().RandomItem(new Random());

            return randomName.Value;

        }

 

        /// <summary>

        /// Returns a string representing a persons full name, randomly selected from actual first and last names

        /// </summary>

        public static string RandomFullName()

        {

            return string.Format("{0} {1}", RandomFirstName(), RandomLastName());

        }

 

        /// <summary>

        /// Returns a string representing a common name suffix, e.g. III, Jr., M.D., etc.

        /// </summary>

        public static string RandomNameSuffix()

        {

            var randomSuffix = dataDocument.Descendants("data").Descendants("suffixes").Descendants("suffix").ToList().RandomItem(new Random());

            return randomSuffix.Value;

        }

 

        /// <summary>

        /// Returns a random company name based on a list of fake company names

        /// </summary>

        public static string RandomCompanyName()

        {

            var randomName = dataDocument.Descendants("data").Descendants("companies").Descendants("company").Descendants("name").ToList().RandomItem(new Random());

            return randomName.Value;

        }

 

        /// <summary>

        /// Returns a string representing a street address, e.g. 123 First Ave.

        /// </summary>

        public static string RandomStreetAddress()

        {

            var randomStreet = dataDocument.Descendants("data").Descendants("addresses").Descendants("streetNames").Descendants("streetName").ToList().RandomItem(new Random());

            var randomStreetSuffix = dataDocument.Descendants("data").Descendants("addresses").Descendants("streetSuffixes").Descendants("streetSuffix").ToList().RandomItem(new Random());

            return string.Format("{0} {1} {2}", RandomInt(1, 1999), randomStreet.Value, randomStreetSuffix.Value);

        }

 

        /// <summary>

        /// Returns a random name that could be a city

        /// </summary>

        public static string RandomCity()

        {

            var randomCity = dataDocument.Descendants("data").Descendants("cities").Descendants("city").Descendants("name").ToList().RandomItem(new Random());

            return randomCity.Value;

        }

 

        /// <summary>

        /// Returns a real US/Canadian State name at random, e.g Texas

        /// </summary>

        public static string RandomStateName()

        {

            var randomState = dataDocument.Descendants("data").Descendants("states").Descendants("state").Descendants("name").ToList().RandomItem(new Random());

            return randomState.Value;

        }

 

        /// <summary>

        /// Returns a real US/Canadian State code at random, e.g TX

        /// </summary>

        public static string RandomStateCode()

        {

            var randomState = dataDocument.Descendants("data").Descendants("states").Descendants("state").Descendants("code").ToList().RandomItem(new Random());

            return randomState.Value;

        }

 

        /// <summary>

        /// Returns a Random 5 digits between 11111 and 99999 to use for a zip code

        /// </summary>

        /// <remarks>Unlikely to produce many real zipcodes that the postoffice would recognize</remarks>

        public static string RandomZipCode()

        {

            return RandomInt(11111, 99999).ToString();

        }

 

        /// <summary>

        /// Returns a real country name at random

        /// </summary>

        public static string RandomCountry()

        {

            var randomCountry = dataDocument.Descendants("data").Descendants("countries").Descendants("country").Descendants("name").ToList().RandomItem(new Random());

            return randomCountry.Value;

        }

 

        /// <summary>

        /// Returns a real looking email address

        /// </summary>

        public static string RandomEmailAddress()

        {

            var randomDomain = dataDocument.Descendants("data").Descendants("domainNames").Descendants("domainName").ToList().RandomItem(new Random());

            var randomDomainSuffix = dataDocument.Descendants("data").Descendants("domainNameSuffixes").Descendants("suffix").ToList().RandomItem(new Random());

            return string.Format("{0}.{1}@{2}.{3}", RandomFirstName(), RandomLastName(), randomDomain.Value, randomDomainSuffix.Value);

        }

 

        /// <summary>

        /// Returns a 10 digit phone number in the format (###) ###-####

        /// </summary>

        /// <remarks>Area codes are unlikely to be real</remarks>

        public static string RandomPhone()

        {

            StringBuilder phone = new StringBuilder();

 

            // Lets generate 10 numbers

            while (phone.Length < 10)

            {

                int next = RandomInt(1, 999);

                phone.Append(next.ToString());

            }

 

            return String.Format("{0:(###) ###-####}", Convert.ToInt64(phone.ToString().Substring(0, 10)));

        }

    }

}

I chose to embed the xml file as a resource within the dll, simply because that way we never need to worry about pathing issues. I used an Extension method I found here to randomly select an XML node:

namespace DataGenerator.Extensions

{

    using System;

    using System.Collections.Generic;

 

    public static class IEnumerableExtensions

    {

        public static T RandomItem<T>(this List<T> list, Random rg)

        {

            if (list == null)

            {

                throw new ArgumentNullException("list");

            }

 

            if (rg == null)

            {

                throw new ArgumentNullException("rg");

            }

 

            int index = rg.Next(list.Count);

            return list[index];

        }

    }

}

Using the class couldn't be easier:

            Console.WriteLine(DataGenerator.Generate.RandomFullName());

            Console.WriteLine(DataGenerator.Generate.RandomStreetAddress());

            Console.WriteLine(DataGenerator.Generate.RandomCity());

            Console.WriteLine(DataGenerator.Generate.RandomStateCode());

            Console.WriteLine(DataGenerator.Generate.RandomZipCode());

            Console.WriteLine(DataGenerator.Generate.RandomCountry());

            Console.WriteLine(DataGenerator.Generate.RandomPhone());

 

Download the full source project (Visual Studio 2010, C# 4.0):

DataGenerator.zip (219.40 kb)


Posted by on Friday, July 30, 2010 5:40 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Asynchronous Programming with ASP.Net MVC Futures

Using the AsyncController

Introduction

The AsyncController is an experimental class offered inside the latest MVC Futures dll to allow developers to write asynchronous action methods.  The usage scenario for this is for action methods that have to make long-running requests, such as going out over the network or to a database, and don’t want to block the web server from performing useful work while the request is ongoing.

In general, the pattern is that the web server schedules Thread A to handle some incoming request, and Thread A is responsible for everything up to launching the action method, then Thread A goes back to the available pool to service another request.  When the asynchronous operation has completed, the web server retrieves a Thread B (which might be the same as Thread A) from the thread pool to process the remainder of the request, including rendering the response.  The diagram below illustrates this point.

Configuration

The asynchronous types are declared in the Microsoft.Web.Mvc namespace in the assembly Microsoft.Web.Mvc.dll.  The first change a developer needs to make is to declare a route as asynchronous.  There are MapAsyncRoute() extension methods to assist with this; these are analogs of the normal MapRoute() extension methods already provided by the MVC framework.  In Global.asax:

routes.MapAsyncRoute(

    "Default",

    "{controller}/{action}/{id}",

    new { controller = "Home", action = "Index", id = "" }

);

A route declared with MapAsyncRoute() can correctly handle both synchronous and asynchronous controllers, so there is no need to create complex routing logic such that sync controllers are serviced by the normal MapRoute() handler and async controllers are serviced by the MapAsyncRoute() handler.  However, a sync route [MapRoute()] cannot in general correctly execute async controllers and methods.

Secondly, if you are using IIS6 or IIS7 classic mode, you need to replace the standard *.mvc handler with its asynchronous counterpart.  Replace these lines in Global.asax (they don’t necessarily appear adjacent to one another):

<add verb="*" path="*.mvc" validate="false" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

<add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

With these:

<add verb="*" path="*.mvc" validate="false" type="Microsoft.Web.Mvc.MvcHttpAsyncHandler, Microsoft.Web.Mvc"/>

<add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="Microsoft.Web.Mvc.MvcHttpAsyncHandler, Microsoft.Web.Mvc"/>

Writing asynchronous action methods

In general, any asynchronous controllers that you author should subclass the AsyncController type.  Remember to import the Microsoft.Web.Mvc namespace.

public class MyAsyncController : AsyncController {

    // ...

}

The default constructor of the MyAsyncController sets the ActionInvoker property to an instance of the AsyncControllerActionInvoker.  This specialized invoker can understand several asynchronous patterns.  You can mix and match these patterns inside of your controllers.  If an ambiguity is found, we do our best to throw a detailed exception.

The AsyncController understands three async patterns.  These patterns can be mixed and matched within a single AsyncController.  Additionally, an AsyncController can contain normal (synchronous) action methods.  This makes it easy to change the base class of your controller from Controller to AsyncController in order to add async methods while allowing your original sync methods to run correctly.

The IAsyncResult pattern

The IAsyncResult pattern is a well-known pattern in the .NET Framework and is documented heavily.  A method pair signature which implements the IAsyncResult pattern is shown below.

public IAsyncResult BeginFoo(int id, AsyncCallback callback, object state);

public ActionResult EndFoo(IAsyncResult asyncResult);

This is the asynchronous analog of a synchronous method with the signature public ActionResult Foo(int id).  Note that the BeginFoo() method takes the same parameters as the Foo() method plus two extra – an AsyncCallback and a state object – and returns an IAsyncResult.  The EndFoo() method takes a single parameter – an IAsyncResult – and has the same return type as the Foo() method.

Standard model binding takes place for the normal parameters of the BeginFoo() method.  The invoker will pass a callback and state object for the BeginFoo() method to consume when its asynchronous task has finished.  When the callback is called, we automatically invoke the EndFoo() method and capture the result, then execute the result just as we would have in a synchronous request.

Only filter attributes placed on the BeginFoo() method are honored.  If a filter attribute is placed on EndFoo(), it will be ignored.  If an [ActionName] attribute is placed on the BeginFoo() method in order to alias it, we will look for an EndFoo() method based on the method name of BeginFoo(), not the aliased action name.  For example:

[ActionName("Bar")]

public IAsyncResult BeginFoo(int id, AsyncCallback callback, object state);

public ActionResult EndFoo(IAsyncResult asyncResult);

This will cause the BeginFoo() method to match requests for Bar rather than Foo.  Note that the completion method is still called EndFoo() instead of EndBar() since it matches the name of the entry method, not the entry alias.

The event pattern

In this pattern, the action method is divided into a setup method and a completion method.  The signatures are below:

public void Foo(int id);

public ActionResult FooCompleted(...);

When a request comes for Foo, we execute the Foo() method.  When the asynchronous operations are completed, we invoke the FooCompleted() method and execute the returned ActionResult.

The invoker will model bind parameters to the Foo() method in the standard way.  Parameters to FooCompleted() are not provided using model binders.  Rather, they come from the AsyncController.AsyncManager.Parameters dictionary, which can be populated as part of the asynchronous setup.  Keys in the dictionary correspond to parameter names of the FooCompleted() method, and any parameters which do not have corresponding keys in the dictionary are given a value of default(T).

The invoker must keep track of the number of outstanding asynchronous operations so that it does not invoke the FooCompleted() method prematurely.  To do this, a counter has been provided, accessible from AsyncController.AsyncManager.OutstandingOperations.  This counter can be incremented or decremented to signal that an operation has kicked off or concluded, and when the counter hits zero the invoker will invoke the completion routine.  For example:

public void Foo(int id) {

    AsyncManager.Parameters["p"] = new Person();

    AsyncManager.OutstandingOperations.Increment();

    ThreadPool.QueueUserWorkItem(o => {

        Thread.Sleep(2000); // simulate some work

        AsyncManager.OutstandingOperations.Decrement();

    }, null);

}

public ActionResult FooCompleted(Person p) {

    // consume 'p'

}

There is also an AsyncController.AsyncManager.RegisterTask() method that is helpful for wrapping calls to IAsyncResult pattern methods from within an event pattern method.  The RegisterTask() method also handles incrementing and decrementing the counter correctly.  For example:

public void Foo(int id) {

    AsyncManager.RegisterTask(

        callback => BeginGetPersonById(id, callback, null),

        ar => {

            AsyncManager.Parameters["p"] = EndGetPersonById(ar);

        });

    AsyncManager.RegisterTask(

        callback => BeginGetTotalUsersOnline(callback, null),

        ar => {

            AsyncManager.Parameters["numOnline"] = EndGetTotalUsersOnline(ar);

        });

}

public ActionResult FooCompleted(Person p, int numOnline) {

    // ...

}

This will kick off two asynchronous tasks and wait for both to finish before executing the FooCompleted() method with the values that were returned.

Only filter attributes placed on the Foo() method are honored.  If a filter attribute is placed on FooCompleted(), it will be ignored.  If an [ActionName] attribute is placed on the Foo() method in order to alias it, we will look for an FooCompleted() method based on the method name of Foo(), not the aliased action name.  For example:

[ActionName("Bar")]

public void Foo(int id);

public ActionResult FooCompleted(...);

This will cause the Foo() method to match requests for Bar rather than Foo.  Note that the completion method is still called FooCompleted() instead of BarCompleted() since it matches the name of the entry method, not the entry alias.

The Foo() method is allowed to return anything.  The invoker ignores the return value of this method; it only cares about the return value of the FooCompleted() method.  This is to allow writing Foo() methods that are easier to unit test.

The delegate pattern

This pattern is very similar to the event pattern, except that the method Foo() returns a parameterless delegate type and there is no FooCompleted() method.  For example:

public Func<ActionResult> Foo(int id) {

    Person p = null;

    int numOnline = 0;

    AsyncManager.RegisterTask(

        callback => BeginGetPersonById(id, callback, null),

        ar => {

            p = EndGetPersonById(ar);

        });

    AsyncManager.RegisterTask(

        callback => BeginGetTotalUsersOnline(callback, null),

        ar => {

            numOnline = EndGetTotalUsersOnline(ar);

        });

    return () => {

        ViewData["p"] = p;

        ViewData["numOnline"] = numOnline;

        return View();

    };

}

Or, more succinctly:

public Func<ActionResult> Foo(int id) {

    AsyncManager.RegisterTask(

        callback => BeginGetPersonById(id, callback, null),

        ar => {

            ViewData["p"] = EndGetPersonById(ar);

        });

    AsyncManager.RegisterTask(

        callback => BeginGetTotalUsersOnline(callback, null),

        ar => {

            ViewData["numOnline"] = EndGetTotalUsersOnline(ar);

        });

    return View;

}

Since this pattern supports only parameterless delegates instead of parameterful delegates, the earlier discussion about AsyncController.AsyncManager.Parameters is not applicable.

Timeouts

There is a Timeout property accessible from AsyncController.AsyncManager.Timeout that specifies the number of milliseconds to wait for a response from the action method before canceling the request.  The default value is 30000 (equal to 30 seconds).  If the action method has not returned by the specified time, we throw a TimeoutException.  Action filters and exception filters may handle this particular exception type if they wish.  Setting the Timeout property to System.Threading.Timeout.Infinite signifies that we will never throw this exception.

The timeout duration can be specified on a per-controller or per-action basis by attributing a class or method with [AsyncTimeout] or [NoAsyncTimeout].

Known issues

-          Asynchronous actions generally cannot be called by synchronous invokers or handlers.  If you receive an exception message about an action being unable to be executed synchronously, ensure that you’re using the MapAsyncRoute() extension method in your Global.asax and that your controller subclasses AsyncController.

-          The asynchronous invoker will not match any method beginning with Begin or End or ending with Completed.  This is to prevent web calls to the BeginFoo(), EndFoo(), and FooCompleted() methods directly.  If you need to make an action with this name accessible to web users, use the [ActionName] attribute to alias the method:

[ActionName("Begin")]

public ActionResult DoSomething();

The above is an example of a normal synchronous method that has been renamed to Begin to work around the invoker’s blocking of this name.

-          If the route that normally handles requests for the application root (/) is an asynchronous route, the Default.aspx file should be removed from the web application.  The Default.aspx file included in the template only works with synchronous requests.


Categories: ASP.Net | Asynchronous | C# | MVC
Posted by Williarob on Thursday, June 18, 2009 6:03 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Sample Scrolling Silverlight Video Playlist 2.0

Since the release of Silverlight 2, there have been a number of requests for me to update my Scrolling Silverlight Video Playlist Sample and I have finally made the time to do just that. I feel it is important to point out that Microsoft Expression Encoder 2 Service Pack 1 is now out and it ships with a handful of new Player templates just for Silverlight 2 including two with a built in Scrolling playlist feature (Frosted Gallery and Silverlight 2 Gallery). 

Still, partly because not everyone has Expression Encoder 2 and mostly because I felt it would be educational to do so, I went ahead and rebuilt the Scrolling Silverlight Video Playlist sample from the ground up for Silverlight 2 in C# and here it is:

This time, instead of using a player from the growing Expression Encoder template library, I went with the opensource Blacklight player which is a nice lightweight player. And rather than add my scroll widget directly to the player as I did with version 1.0, I chose to keep it seperate, and created a 'ScrollWidget' User Control that could be used in other projects (for example as a thumbnail scroller for photos, or as a toolbar) with only minor modification.

As always, the complete source code is available:

ScrollingPlaylist2.zip (1.22 mb)

[ Special thanks to Sean at FlawlessCode.com for developing this Silverlight Extension for BlogEngine.NET ]


Categories: C# | Silverlight
Posted by Williarob on Thursday, April 30, 2009 8:47 AM
Permalink | Comments (5) | Post RSSRSS comment feed

Process and Thread Basics

Programs, Processes and Threads

In .NET terms, a program can be defined as an assembly, or group of assemblies, that work together to accomplish a task. Assemblies are little more than a way of packaging instructions into maintainable elements and are generally compiled into a dynamic link library (DLL) or an executable (EXE), or a combination of the two.

A process gives a program a place to run, allowing access to memory and resources. Generally, each process runs relatively independent of other processes. In particular, the memory where your program variables will reside is completely separate from the memory used by other processes. Your email program cannot directly assign a new value to a variable in the web browser program. If your email program can communicate with your web browser—for instance, to have it open a web page from a link you received in email—it does so with some form of communication that takes much more time than a memory access.

By putting programs into processes and using only a restricted, mutually agreed-upon communication between them has a number of advantages. One of the advantages is that an error in one process will be less likely to interfere with other processes. Before multitasking operating systems, it was much more common for a single program to be able to crash the entire machine. Putting tasks into processes, and limiting interaction with other processes and the operating system, has greatly added to system stability.

All modern operating systems support the subdivision of processes into multiple threads of execution. Threads run independently, like processes, and no thread knows what other threads are running or where they are in the program unless they synchronize explicitly. The key difference between threads and processes is that the threads within a process share all the data of the process. Thus, a simple memory access can accomplish the task of setting a variable in another thread. Every program will have at least one thread.

In his book ".NET Multithreading" Alan Dennis compares a Process to a house and a thread to a housecat. He writes:

The cat spends most of its time sleeping, but occasionally it wakes up and performs some action, such as eating. The house shares many characteristics with a process. It contains resources available to beings in it, such as a litter box. These resources are available to things within the house, but generally not to things outside the house. Things in the house are protected from things outside of the house. This level of isolation helps protect resources from misuse. One house can easily be differentiated from another by examining its address. Most important, houses contain things, such as furniture, litter boxes, and cats.

Cats perform actions. A cat interacts with elements in its environment, like the house it lives in. A housecat generally has a name. This helps identify it from other cats that might share the same household. It has access to some or the entire house depending on its owner’s permission. A thread’s access to elements may also be restricted based on permissions, in this case, the system’s security settings.

Multitasking

Multitasking means that more than one program can be active at a time. You may take it for granted that you can have an email program and a web browser program running at the same time. Yet, not that long ago, this was not the case. In the days of DOS you would need to save and close your spreadsheet before opening your word processor. With the advent of Windows, you could open multiple applications at once. Windows 3.x used something called Cooperative Multitasking which is based on the assumption that all running processes will yield control to the operating system at a frequent interval. The problem with this model was that not all software developers followed these rules and a program that did not return control to the system, or did so very infrequently, could destabilize the operating system, causing it to "lock up". When Windows 3.x started a new application, that application was invoked from the main thread. Windows passed control to the application with the understanding that control would quickly be returned to windows. If that didn't happen, all other running applications including the operating system could no longer execute instructions. Today, Windows employs Preemptive Multitasking. In this model, instead of relying on programs to return control to the system at regular intervals, the OS simply takes it. 

The main thread of a typical windows program executes a loop (Called a message pump). The loop checks a message queue to see if there is work to do and if there is, it does the work. For example, when a user clicks on a button in a windows application the click event adds work to the message queue indicating which method should be executed. This method is of course known as an event handler. While the loop is executing an event handler, it cannot process additional messages. Multithreading (literally using more than one thread) is how we can work around this limitation. Instead of having the main thread that was assigned to this program do the time consuming work, we assign the work to a seperate thread and have it do the work.

There are a number of ways to create and manage these new threads - using System.Threading, creating a delegate method, implementing the Event Based Asynchronous Pattern, using waithandles, etc. and I intend to explore all of them future articles. In a single core processor, this execution on a separate thread would be periodically interrupted by the operating system to allow other threads a chance to get work done; but after decades in a world where most computers had only one central processing unit (CPU), we are now in a world where only "old" computers have one CPU. Multi-core processors are now the norm. Therefore, every software developer needs to Think Parallel.

Multithreading

Multithreading allows a process to overlap I/O and computation. One thread can execute while another thread is waiting for an I/O operation to complete. Multithreading makes a GUI (graphical user interface) more responsive. The thread that handles GUI events, such as mouse clicks and button presses, can create additional threads to perform long-running tasks in response to the events. This allows the event handler thread to respond to more GUI events. Multithreading can speed up performance through parallelism. A program that makes full use of two processors may run in close to half the time. However, this level of speedup usually cannot be obtained, due to the communication overhead required for coordinating the threads.


Posted by Williarob on Saturday, June 28, 2008 9:00 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Use Regex to block specific IP addresses or ranges

Perhaps your feedback page is being hammered by spammers, perhaps your customers are receiving a lot of scam emails from Nigeria, perhaps you are having trouble with stolen credit card information being entered on your site. You have identified some Bad IP addresses you need to block but how do you go about blocking them if you have your site hosted somewhere and you don't have access to the apache or IIS web server directly? I wrote the functions below for just this purpose.

using System;
using System.Data;
using System.Web;
using System.Web.Caching;
using System.Text.RegularExpressions;
namespace BlockIPs
{
public partial class _Default : System.Web.UI.Page
{
public Cache MyCache = HttpContext.Current.Cache;
private static readonly Object lock_object = new Object();
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(isIpBlocked(Request.ServerVariables["Remote_Addr"]));
}
/// <summary>
/// Compares the passed IP address to an external list of Bad IP Addresses
/// </summary>
/// <param name="strIP"></param>
/// <returns>boolean result</returns>
/// <remarks>some of the ips in the block list are like xxx.xxx.0.0 this means all Ips that start xxx.xxx should be blocked...</remarks>
bool isIpBlocked(string strIP)
{
if (!IsValidIP(strIP))
{
return false;
}
String CacheKey = "IPBlocklist";
DataSet DS = (DataSet)MyCache[CacheKey];
if (DS == null)
{
lock(lock_object) //If this file is being hit 1000s times per second only need to make 1 call to the file, the rest will wait until cache is ready.
{
DS = new DataSet();
DS.ReadXml(Server.MapPath("BlockedIPs.xml"));
DS.Tables[0].PrimaryKey = new DataColumn[] {DS.Tables[0].Columns["IP"]};
CacheDependency cd = new CacheDependency(Server.MapPath("BlockedIPs.xml"));
MyCache.Insert(CacheKey, DS, cd, System.DateTime.Now.AddMinutes(10), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
}
}
// first check to see if the ip is in the table
if (DS.Tables[0].Rows.Contains(strIP))
{
return true;
}
// split the incoming ip into octets
string [] octets = strIP.Split('.');
// set up some regex patterns
string pattern1 = String.Format(@"^{0}\.{1}\.{2}\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$", octets[0],octets[1], octets[2]);
string pattern2 = String.Format(@"^{0}\.{1}\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$", octets[0], octets[1]);
string pattern3 = String.Format(@"^{0}\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$", octets[0]);
//create our Regular Expression objects
Regex check1 = new Regex(pattern1); //Checks for xxx.xxx.xxx.0
Regex check2 = new Regex(pattern2); //Checks for xxx.xxx.0.0
Regex check3 = new Regex(pattern3); //Checks for checks for xxx.0.0.0
foreach (DataRow dr in DS.Tables[0].Rows)
{
if(IsValidIP(dr["IP"].ToString()))
{
string[] checkOctets = dr["IP"].ToString().Split('.');
if((checkOctets[1] == "0") && (checkOctets[2] == "0") && (checkOctets[3] == "0"))
{
if(check3.IsMatch(dr["IP"].ToString(),0))
{
return true;
}
}else if ((checkOctets[2] == "0") && (checkOctets[3] == "0"))
{
if (check2.IsMatch(dr["IP"].ToString(), 0))
{
return true;
}
}else if (checkOctets[3] == "0")
{
if (check1.IsMatch(dr["IP"].ToString(), 0))
{
return true;
}
}
}
}
return false;
}
/// <summary>
/// method to validate an IP address
/// using regular expressions. The pattern
/// being used will validate an ip address
/// with the range of 1.0.0.0 to 255.255.255.255
/// </summary>
/// <param name="addr" class="success">Address to validate</param>
/// <returns></returns>
public bool IsValidIP(string addr)
{
//create our match pattern
string pattern = @"^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$";
//create our Regular Expression object
Regex check = new Regex(pattern);
//boolean variable to hold the status
bool valid = false;
//check to make sure an ip address was provided
if (addr == "")
{
//no address provided so return false
valid = false;
}
else
{
//address provided so use the IsMatch Method
//of the Regular Expression object
valid = check.IsMatch(addr, 0);
}
//return the results
return valid;
}
}
}

Download the complete ASP.Net 2.0 Solution which also includes the same functions presented as a Visual Basic Webservice and the xml file containing a starter set of known bad IP addresses to block that I found on this site. You could use this technique to check for bad IPs on Application Start in the Global.asax to block visitors to your site completely, or just on specific pages, or prior to processing a credit card transaction, or prior to posting a comment or feedback form, etc., etc.  


Posted by Williarob on Tuesday, November 20, 2007 9:48 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Move View State to the Server

In his talk "Hidden Gems in ASP.NET 2.0" at Tech Ed 2007 Jeff Prosise showcased a number of really useful but little known features built into ASP.Net 2.0. The one feature that I implemented immediately on all my sites after his talk was his SessionPageStateAdapter class.

This class moves the bulk of the Viewstate text out of the hidden field on the page and into a session variable on the server, and requires remarkably few lines of code. Follow these steps to implement it on your site:

  1. Create  a folder in your application root and name it "App_Browsers"
  2. Add a new XML File to this folder. It doesn't matter what you call it as long as it has a ".browser" extention. I called mine "Default.browser".
  3. Paste in the following code:

    <browsers>
      <browser refID="Default">
        <controlAdapters>
          <adapter controlType="System.Web.UI.Page" adapterType="SessionPageStateAdapter" />
        </controlAdapters>
      </browser>
    </browsers>

  4. Create a new class file (in your App_Code dir for a web site or anywhere in a Web Project) and name it "SessionPageStateAdapter"
  5. Paste in the following code:

    using System;
    using System.Web.UI;
    /// <summary>
    /// Summary description for SessionPageStateAdapter
    /// </summary>
    public class SessionPageStateAdapter : System.Web.UI.Adapters.PageAdapter
    {
      public override PageStatePersister GetStatePersister()
      {
        return new SessionPageStatePersister(this.Page);
      }
    }

That's it! It reduced the viewstate field on this page (at the time of writing) from 9440 characters to just 129 characters!

  


Categories: ASP.Net
Posted by Williarob on Thursday, October 25, 2007 1:15 PM
Permalink | Comments (0) | Post RSSRSS comment feed