Mind Mate: Taking Notes with rich text support

(for background on Mind Mate, click here)

Today, I released a new version (0.4) of Mind Mate on GitHub. The chief improvement is the rich text editing capabilities for notes as demonstrated below.

When the focus is inside Note Editor, the ribbon switches to following Contextual tab.

If the cursor is inside a table, ‘Table Tools’ contextual tab becomes available.

So, following are now supported in Note editor:

  • Bold, Italic, Underline and Strikethrough
  • Subscript and Superscript
  • Text Color and Highlight
  • Font Family and Size
  • Bullets and Numbered Lists
  • Text Alignment and Indent / Outdent
  • Headings
  • Clear Formatting
  • Insert Table
  • Table Tools
    • Insert Row (above, below)
    • Insert Column (left, right)
    • Delete Row, Column or Table
    • Move Row (up, down)
    • Move Column (left, right)

Mind Mate: Mind Mapping on Windows 7 and 8

(for background on Mind Mate, click here)

I have been developing Mind Mate on Windows 10 machine, so wasn’t sure how it is going to behave on earlier versions of OS. Today, I tested it on Windows 7 and 8 using VMs made available by Microsoft.

Mind Mate worked perfectly on Windows 8 but encountered few issues on Windows 7 related to Windows Ribbon Control. These issues are:

– Images in PNG format are not displayed in the ribbon. Seems like Ribbon control on Win7 only supports BMP, that too generated in a certain version of BMP specification. I found that only PixelFormer knows how to generate the right BMP file for Windows 7 Ribbon control.

– Controls don’t layout properly after initial launch, it requires resizing the main window once, then it starts working fine.

– Non true type fonts are not supported.

These issues are resolved in the new Build. Download it from here and give it a go.

Developed Mind Mapping software–codenamed ‘Mind Mate’

Mind Map is a graphical way of representing concepts and ideas. It starts with the main idea at the center with branches going into details.

Personally, I use it for all my notes taking, to-do lists, managing project information etc. Probably it goes beyond what normal usage of the term Mind Map implies but I found many people using Mind Mapping software in the same way. The appeal of Mind Mapping software, in the regard, is the ability to handle the depth of information. Due to outlining you focus on the level of information you want, dig deeper into a topic or zoom out to the headlines with ease.

FreeMind and XMind are the most popular software out there. Personally, I prefer FreeMind as it is more suitable to the usage style I described above. XMind is more focused towards presentation, rather than daily usage for notes taking. Unfortunately, FreeMind is a not being developed very actively.

Since last couple of years, I have been developing my own Mind Mapping software on Github. It started just as a pastime and somehow I managed to put in some hours week after week. It has been a fun ride and a very good learning experience. I switched to it for my daily use for a few months now. Today I prepared an installer for MindMate to make it more accessible. Please download it and give it a short. I will wait for your feedback.

It would be my pleasure if you are interested in contributing to the project in any role. It could be as a developer, document writer, tester or just providing feedback as a user.

Download Windows Installer or Portable Zip from here: MindMate

(MindMate only supports Windows 10 for now, will test and build it for earlier version soon. MindMate works fine on Windows 10, 8 and  7)

Developed a basic, light-weight library for scheduling tasks in C# .Net

Source code can be found at GitHub

TaskSchedular

TaskScheduler is a simple and efficient C# .Net library that runs given tasks at the specified date and time.

  • Efficient : There is no polling. Only runs when a task is due. This is achieved though AutoResetEvent.
  • Simple : Merely 8 KB in size. Pretty easy to use but addresses limited number of use cases.

Background

.Net Framework comes with various Timer classes which give us the ability to run a task periodically.

Apart from Timers which run periodically, we don’t have any class which executes tasks at a given time. A usual work around is to use Timer of a second or so (based on your need), then keep checking if any task is due in timer’s event and execute the task when due. In order to be more resource friendly, TaskSchedular takes a different approach instead of continuous polling for task due date.

How TaskScheduler Works

It runs in it’s own thread and doesn’t consume any CPU resouces till a task is due. This is acheived through Wait Handle (AutoResetEvent). All scheduled tasks are executed in the same thread, which means:

  • tasks are not running in GUI thread so any code which is related to GUI should be invoked on the GUI thread. See this blog post for running code in GUI thread using Control.Invoke.
  • tasks are never executed in parallel as there is only one thread. This has following upshots:
    • saves us from thread synhronization issues within tasks.
    • this library might not the the right one for you if you need more parallelism. In such a case, check out alternatives like Quartz.NET and FluentScheduler.

Usage

Starting TaskScheduler
var schedular = new TaskSchedular.TaskSchedular();
schedular.Start();
Adding task
schedular.AddTask(new TaskSchedular.Task()
    {
        StartTime = DateTime.Now.AddSeconds(30),
        TaskAction = () =>
        {
            // do some work here
            System.Threading.Thread.Sleep(300);
        },
        Recurrance = TimeSpan.FromSeconds(30)
    });

Note: TaskSchedular is has a tolerance of 1 second by default, that is, if a task is due within a second, it will execute it right away.

MouseHover event in Windows Forms .Net – Generating it repeatedly

MouseHover Event

When mouse is stationary for some time over a Windows Forms control, Mouse Hover event is generated. This event is generated only once during mouse’s stay and movement over a control. If mouse leaves and re-enters the control, system again starts tracking for Mouse Hover and will generate the event accordingly.

A common use of Mouse Hover event is to display tool tip.

Following code attaches MouseHover handler to a control.

myControl.MouseHover += myControl_MouseHover;

The handler just logs that event is generated.

void myControl_MouseHover(object sender, EventArgs e)
{
    System.Diagnostics.Debug.WriteLine(
        "MouseHover event generated");
}

Generating Mouse Hover event repeatedly

In some scenarios, it could be desirable to generate Mouse Hover event repeatedly inside a control, whenever mouse becomes stationary. For instance, this could be useful if you have a user-drawn control and want to generate Mouse Hover events for individual user-drawn components. To achieve this, we need to reset the Hover event every time it is generated. This can be done by calling TrackMouseEvent method in MouseMove event.

Adding MouseMove event handler…

myControl.MouseMove += myControl_MouseMove;

Calling TrackMouseEvent to reset tracking of Hover event:

void myControl_MouseMove(object sender, MouseEventArgs e)
{
    const uint HOVER_DEFAULT = 0xFFFFFFFF;
    TRACKMOUSEEVENT trackMouseEvent = 
        new TRACKMOUSEEVENT(TMEFlags.TME_HOVER, this.Handle, HOVER_DEFAULT);
    TrackMouseEvent(ref trackMouseEvent);
}

As TrackMouseEvent is a native method, we need to define it using DllImport along with the TRACKMOUSEEVENT structure.

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern int TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack);

[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct TRACKMOUSEEVENT
{
    public Int32 cbSize;    // using Int32 instead of UInt32 is safe here, and this avoids casting the result  of Marshal.SizeOf()
    [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
    public TMEFlags dwFlags;
    public IntPtr hWnd;
    public UInt32 dwHoverTime;

    public TRACKMOUSEEVENT(TMEFlags dwFlags, IntPtr hWnd, UInt32 dwHoverTime)
    {
        this.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(TRACKMOUSEEVENT));
        this.dwFlags = dwFlags;
        this.hWnd = hWnd;
        this.dwHoverTime = dwHoverTime;
    }
}


/// <summary>
/// The services requested. This member can be a combination of the following values.
/// </summary>
/// <seealso cref="http://msdn.microsoft.com/en-us/library/ms645604%28v=vs.85%29.aspx"/>
[Flags]
public enum TMEFlags : uint
{
    /// <summary>
    /// The caller wants to cancel a prior tracking request. The caller should also specify the type of tracking that it wants to cancel. For example, to cancel hover tracking, the caller must pass the TME_CANCEL and TME_HOVER flags.
    /// </summary>
    TME_CANCEL = 0x80000000,
    /// <summary>
    /// The caller wants hover notification. Notification is delivered as a WM_MOUSEHOVER message.
    /// If the caller requests hover tracking while hover tracking is already active, the hover timer will be reset.
    /// This flag is ignored if the mouse pointer is not over the specified window or area.
    /// </summary>
    TME_HOVER = 0x00000001,
    /// <summary>
    /// The caller wants leave notification. Notification is delivered as a WM_MOUSELEAVE message. If the mouse is not over the specified window or area, a leave notification is generated immediately and no further tracking is performed.
    /// </summary>
    TME_LEAVE = 0x00000002,
    /// <summary>
    /// The caller wants hover and leave notification for the nonclient areas. Notification is delivered as WM_NCMOUSEHOVER and WM_NCMOUSELEAVE messages.
    /// </summary>
    TME_NONCLIENT = 0x00000010,
    /// <summary>
    /// The function fills in the structure instead of treating it as a tracking request. The structure is filled such that had that structure been passed to TrackMouseEvent, it would generate the current tracking. The only anomaly is that the hover time-out returned is always the actual time-out and not HOVER_DEFAULT, if HOVER_DEFAULT was specified during the original TrackMouseEvent request.
    /// </summary>
    TME_QUERY = 0x40000000,
}

Above ensures that Hover event is generated whenever mouse stays still for sometime, and not only once after mouse enters the control.

Book Review: Threading in C# by Joseph Albahari

Threading is a complex subject, it is easy to get yourself entangled in threads which don’t behave as you expect them to. There are many constructs and approaches to synchronize threads or achieve parallelism, each with its own quirks and advantages. There are good old threads, there are thread pools, task parallelism, Parallel class, Async methods and Timers. Then there are a myriad ways of synchronizing thread like locks, spin locks, mutex, semaphores, event wait handles, concurrent collections, Synchronization attribute, Memory Barriers, Interlocked class, Monitor’s Wait/Pulse and Reader Writer Lock . To make sense of it all,  Threading in C# by Joseph Albahari is thorough reference on the subject. It is available online, free of charge in hypertext format which makes it particularly useful as a reference.

csianThreading in C# is also there as a chapter in somewhat abridged form in author’s book ‘C# in a Nutshell‘.

 

Study Notes for Microsoft Exam: Developing ASP.NET MVC Web Applications (70-486)

Took Microsoft Exam 70-486 which part of MCSD certification. I spend about 2 weeks studying the material and took some notes which are posted here. Notes are not complete in the sense that they don’t cover the full syllabus – half of my notes are scattered in different places which will be incorporated here later (hopefully).

Code First Migrations:

Three step process (use Package Manager Console):

  1. enable-migrations -ContextTypeName MyProject.Models.StudentDBContext
    • Creates Configuration class with Seed method
    • Needs to be executed only once to setup migrations
  2. add-migration MyFirstMig
    • Creates {DateStamp}_MyFirstMig.cs in Migrations folder
    • Execute it after each change to model
  3. update-database
    • Execute it to apply changes to database

Data Annotations:

  • [Required]
  • [Range(5, 10)]
  • [StringLength(5)]
  • [DataType(DataType.Date)]         (enum DataType { CreditCard, Currency, Custom, Date, DateTime, Duration, EmailAddress, Html, ImageUrl, MultilineText, Password, PhoneNumber, PostalCode, Text, Time, Upload, Url, })
  • [DisplayFormat(DataFormatString = “{0:d}”)]

Model Validation:

  • In Controller’s Create or Edit action (server):
[HttpPost]
public ActionResult Create(Movie movie)
{
   if (ModelState.IsValid)
   {
      db.Movies.Add(movie);
      db.SaveChanges();
      return RedirectToAction("Index");
   }

   return View(movie);
}
  • In view (browser):
<div class="editor-field">
   @Html.EditorFor(model => model.Title)     
   @Html.ValidationMessageFor(model => model.Title)
</div>

Cross Site Scripting Attack

  • Add @AntiForgeryToken() in view inside form element
  • Add [ValidateAntiForgeryToken] attribute on form post actions

Asynchronous Programming with async and await:

image001

Bundling and Minification

  • Good Article: Link
  • Most browsers limit the number concurrent requests to the same domain to six
  • To disable
<system.web>
    <compilation debug="true" />
    <!-- Lines removed for clarity. -->
</system.web>
  • Can be overwritten in code
BundleTable.EnableOptimizations = true;
  • Creating script bundle
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                 "~/Scripts/jquery-{version}.js"));
  • Creating style bundle
bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
          "~/Content/themes/base/jquery.ui.core.css",
          "~/Content/themes/base/jquery.ui.resizable.css",
          "~/Content/themes/base/jquery.ui.selectable.css",
          "~/Content/themes/base/jquery.ui.accordion.css" ));
  • Adding reference to bundles in view
@Styles.Render("~/Content/themes/base/css", "~/Content/css")
@Scripts.Render("~/bundles/modernizr")

<script src='@Scripts.Url("~/bundles/modernizr")' async> </script>

 

  • Can use ‘*’ wildcard and IncludeDirectory function
bundles.Add(new StyleBundle("~/jQueryUI/themes/baseAll")
    .IncludeDirectory("~/Content/themes/base", "*.css"));
  • .min files are selected for release (jquery-1.7.1.min.js)
  • -vsdoc files are ignored (they are for intellisense)
  • Bundle Transformation
    • Implement IBundleTransform
using System.Web.Optimization;

public class LessTransform : IBundleTransform
{
    public void Process(BundleContext context, BundleResponse response)
    {
        response.Content = dotless.Core.Less.Parse(response.Content);
        response.ContentType = "text/css";
    }
}
  • Add transformation
var lessBundle = new Bundle("~/My/Less").IncludeDirectory("~/My", "*.less");
lessBundle.Transforms.Add(new LessTransform());
lessBundle.Transforms.Add(new CssMinify());
bundles.Add(lessBundle);

Using OAuth providers with MVC:

  • Register your site with provider and Receive parameters (such as key or id, and secret)
  • Register your application as Provider’s client: RegisterFacebookClient(            appId: “111111111111111”,            appSecret: “a1a1aa111111111a111a111aaa111111”);

Interaction among View, Layout page (_Layout.cshtml) and other pages

@RenderBody() Called from _Layout.cshtml to render the body of the requested page at the right place within layout.
@RenderSection(“scripts”, required: false) Called from _Layout.cshtml to rendor a section if defined in the requested page.- Section definition is optional if required is false- Section definition on requested page

@section Scripts {

   @Scripts.Render(“~/bundles/jqueryval”)

}

@RenderPage(“MyView.cshtml”, MyModel) Renders the specified page as part of the requested page. Similar to @Html.Partial(“MyView”)

 

WCF vs ASP.Net Web API

image002

Others

  • Don’t use HTTP GET request for delete, edit or create options as they open security holes (link)
  • Fiddler, a web debugging tool which logs all HTTP / HTTPS traffic. (http://www.telerik.com/fiddler/)

Authorization

  • [Authorize(Roles=”Admin,PowerUser“, Users=”Mark“)]
    • Implements IAuthorizationFilter which has one method OnAuthorization
  • AuthorizeAttribute.AuthorizeCore method: When overridden, provides an entry point for custom authorization checks.
  • [AllowAnonymous] This attribute on Action will override the Authroize on Controller and wise versa

 

Browser / Feature Detection and Compatibility

  • Video tab with fall backs
<video>
<source src="video.mp4" type='video/mp4' />
<source src="video.webm" type='video/webm' />
<object type="application/x-silverlight-2">
<param name="source" value="http://url/player.xap">
<param name="initParams" value="m=http://url/video.mp4">
</object>
Download the video <a href="video.mp4">here</a>.
</video>

 

  • Display modes (by default we have regular mode and Mobile mode)
    • Mobile.cshtml will be used instead of Index.cshtml automatically when page is accessed through a mobile
    • Add new DefaultDisplayMode (WP7.cshtml)

 

DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("WP7")
  {
      ContextCondition = ctx => ctx.GetOverriddenUserAgent().Contains("Windows Phone OS")
  });

 

  • Setting viewport to device width <meta name=”viewport” content=”width=device-width” />
  • CSS @media query

 

@media only screen and (max-width: 850px) {
    .site-title {
        color: #c8c8c8;
    }
}

@media (min-width: 768px) and (max-width: 979px) and (orientation:portrait) {…

 

  • Check if user is on mobile device: Browser.IsMobileDevice
  • CSS Vendor Prefixes
    • -ms-, -mso- (Mircosoft); -moz- (Mozilla); -webkit- (Apple, Google); -o-, xv- (Opera)
    • Example: -moz-border-radius: 18px;

 

Razor View Templates

 

  • EditorFor template (used with @Html.EditorFor() helper)
    • Path: ~/Views/ControllerName/EditorTemplates/Article.cshtml

 

@model MyMVCApplication1.Article
@if (Model != null)
{
    @Html.TextBox("", Model.Title)
    @Html.TextBox("", Model.Body)
}
else
{
    @Html.TextBox("", string.Empty)
    @Html.TextBox("", string.Empty)
}

 

  • DisplayTemplate (used with @Html.DisplayFor() helper)
    • Path: ~/Views/ControllerName/DisplayTemplates/<Type Name>.cshtml

 

Action Filters

 

    • Authorization filters – Implements the IAuthorizationFilter attribute.
    • Action filters – Implements the IActionFilter attribute.
    • Result filters – Implements the IResultFilter attribute.
    • Exception filters – Implements the IExceptionFilter attribute.
  • Authorization filters are always executed before action filters
  • Filter’s Order parameter can be used to control the order in which filters of same type are executed
  • Filter’s AllowMultiple parameter can be used to run filter only once
  • ActionFilterAttributeimplements bothIActionFilter andIResultFilter and drives fromActionFilterAttribute
    • It has methods: OnActionExecuting, OnActionExecuted, OnResultExecuting, OnResultExecuted
  • Add filter globally to all actions Add(new RequireHttpsAttribute());
    • filters is GlobalFilters.Filters passed as parameter to FilterConfig
  • Useful Fitlers: HandlerError, OutputCache, Authorize

 

Web Accessibility Initiative-Accessible Rich Internet Applications (WAI-ARIA)

  • aria-labelledby=”name_label” This attribute on input field can an link it to the label which can deliver meaning otherwise delivered visually
  • aria-required defines a mandatory input field

 

Search Engine Optimization

  • txt file – create robot exclusion rules (list pages that should be indexed by search engine)
  • Have meaningful url. Rather than com/1, use mysite.com/<record title>

 

Globalization

  • Accept-Language: en-US,en;q=0.8 (Request Header presented to server)
  • en is Language, US is Locale. Language is at a higher level than locale.
  • <globalization culture=”auto” uiculture=”auto” enableclientbasedculture=”true”/> (enable client based culture in Web.Config)
  • Thread.CurrentThread.CurrentUICulture (find current culture)
  • Use resource files
    • keeps strings in resource files (.resx)
    • create separate files for each language (MyResFile.resx, MyResFile.es-MX.resx)
    • access string using MyResFile.MyLabel1
  • An Alternative to resource files is to use localized views
  • There no way to determine culture in javascript (server has to send it back)
  • Setting culture for jQuery in browser (use anyone of the two)
    • <script>preferCulture(language);</script>
    • $.global.preferCulture(language)
  • Manually set culture on server (may be based on user selection)
    • CurrentThread.CurrentUICulture = new CultureInfo(“es-MX”);
  • Create satellite assemblies (dll) to separate culture specific resouces (only required resources are loaded in memory)

 

Action Attributes (other than filters and attributes covered in else where)

  • RequireHttps
  • ValidateInputTo exclude a field [ValidateInput(true, Exclude = “ArbitraryField”)]
  • AllowHtml
  • ActionName
  • ChildActionOnly (action can’t be accessed directly by client, has to be called from a view using @Html.Action(“MyView”) or RenderAction )

 

Error Handling

  • [HandleError(ExceptionType=typeof(NullReferenceException), View=”MyErrorView”)]
    • Action attribute for handling exception
    • Implements IExceptionFilter that has OnException method
    • By default MVC display ~/Views/Shared/Error
  • Application_Error method in global.asax class (for unhandled exception that makes through the stack)
  • IsCustomErrorEnabled

Action Results

  • All action results derive from ActionResult class
Action Result Type Action Helper method Comments
ViewResult View Renders Html, derive from ViewBaseResult
PartialViewResult PartialView Renders Html, derive from ViewBaseResult
JsonResult Json
JavaScriptResult JavaScript
RedirectResult Redirect
RedirectToRouteResult RedirectToActionRedirectToRoute
FileResult File
ContentResult Content Can be used to return pdf, xml etc.
EmptyResult N/A (return null)

 

  • A custom action result can be created by inheriting from ActionResult class and overriding void ExecuteResult(ControllerContext ctx) method

Model Binders

  • DefaultModelBinder Maps a browser request to a data object
  • LinqBinaryModelBinder Maps a browser request to a LINQ object
  • Creating a custom model binder
  • Implement IModelBinder interface with one method: public object BindModel(ControllerContextcontrollerContext,ModelBindingContextbindingContext)
  • Setting custom binder for a model class
[ModelBinder(typeof(MyModelBinder))]
public class MyModel
{       ...     }
  • Another way of doing it

ModelBinders.Binders.Add(typeof(MyModel),newMyModelBinder())

 

  • Extending DefaultModelBinder class
    • public class MyBinder : DefaultModelBinder
  • Extend BindProperty method (loops through every model property one by one)
    • protected override void BindProperty(ControllerContext contContext, ModelBindingContext bindContext, PropertyDescriptor propDesc)
    • can be used to override default behavior for certain properties e.g. combine date and time from two fields into one property
    • call base.BindProperty for properties you want to bind using default binding
  • Registor the new binder

ModelBinders.Binders.DefaultBinder =newMyBinder();

 

  • Weakly typed model, all parameter with login prefix will map to LoginUser model

public ActionResult Login([Bind(Prefix=”login”)]LoginUser user)

  • Exclude / Include paramters for Bind

public ActionResult Save([Bind(Exclude = “Salary”)]Employee emp)

 

  • Four value providers: FormsValueProvider, QueryStringValueProvider, HttpFileCollectionValueProvider, RouteDataValueProvider
  • Three types of model binding: Strong, Weak and using ValueProvider.

 

Routes

  • Defining routes (IgnoreRoute should come before MapRoute)
public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new
            {
                controller = "Home",
                action = "Index",
                id = UrlParameter.Optional
            },
            constraints: new { id = @"\d+" }
            );
        }

 

  • In case of Areas, providing a link to action

@Html.ActionLink(“Exam Detail”, “Exam”, “Detail”, new { area=”ExamSite”}, null)

 

  • Extending default MvcRouteHandler
    • public class MyCustomRouteHandler : MvcRouteHandler
    • Override protected override IHttpHandler GetHttpHandler(RequestContext reqContext)
    • Registering route handler
routes.MapRoute(
                "Home",
                "{controller}/{action}",
                new { controller = "Home", action = "Index" }
                ).RouteHandler = new MyCustomRouteHandler();
  • Implementing IRouteHandler (has one method GetHttpHandler)
    • Registration is bit different from above

Route customRoute = new Route(“custom/{name}”, new MyRouteHandler(“My Route”));

routes.Add(“route-name”, customRoute);

ControllerFactory

  • For custom controller factory, implement IControllerFactory which has three methods: CreateController, ReleaseController, and GetControllerSessionBehavior.
  • Register controller factory in the Global.asax Application_Start method: ControllerBuilder.Current.SetControllerFactory(typeof(MyControllerFactory());
  • Link: Deep Drive into IControllerFactory

View Engine

  • Both RazorViewEngine and Web Forms engine derive from VirtualPathProviderViewEngine which in turn implements IViewEngine
  • IViewEngine has three methods: FindView, FindPartialView and ReleaseView
  • The two find methods return ViewEngineResult object which contains IView
  • IView has one method public void Render(ViewContext viewContext, System.IO.TextWriter writer)

MVC Life Cycle

  • Request
  • UrlRoutingModule selects the Route object
  • Based on the route, UrlRoutingModule obtains an object that implements IRouteHandler (typically it is MvcRouteHandler)
  • MvcRouteHandler creates an instance of MvcHandler which implements IHttpHandler
  • MvcHandler obtains reference to IControllerFactory (typically DefaultControllerFactory)
  • MvcHandler create Controller instance by help of IControllerFactory
  • MvcHandler calls controller’s Execute method
  • ControllerActionInvoker object associated with Controller determines which action method to call
  • Response
  • Controller action create ViewResult
  • ViewResult calls ViewEngine
  • ViewEngine calls View
  • View renders the Response

HTTP Handlers

  • Implement IHttpHandler which has a method ProcessRequest and a property IsReusable
  • Register handler
      <system.web>
        <httpHandlers>
          <add verb="*" path="SampleHandler.new" type="SampleHandler" />
          <add verb="*" path="*.SampleFileExtension" type="SampleHandler2 " />
        </httpHandlers>
      </system.web>

Http Modules

    <system.web>
      <httpModules>
        <add name="HelloWorldModule" type="HelloWorldModule"/>
      </httpModules>
    </system.web>

Windows Identity Foundation

Async / Await and SynchronicationContext (C# .Net)

Following innocuous looking async / await code will cause deadlock.

private void button1_Click(object sender, EventArgs e)
{
  Task<string> task1 = LongRunningProcess();

  textBox1.Text = task1.Result;
}

public async Task<string> LongRunningProcess()
{
  string txt = await Task.Run(() =>
    {
      System.Threading.Thread.Sleep(5000);
      return "results";
    }
  );

  return txt;
}

To understand why, lets go into what await does in the above case.

1 Execution starts when the button is clicked and button1_Click event is fired on the UI thread.
2 The method, named LongRunningProcess, is invoked.
3 The lamda expression passed to Task.Run() executes in a separate thread (lets call it thread_B)
4 Now await keyword is encountered, rather than completing the rest of the method, control returns back to button1_Click event to continue execution after the call to long running method.
5 Calling task1.Result makes the current thread wait on thread_B to complete and provide the results. So UI thread is now waiting for thread_B to complete.
6 As thread_B completes the task, it has to run the remaining part of long running method. Run time ensures that this code executes on the right context. That is, if the initial part of long running method was executed on the UI thread, then remaining part will also be executed in the same thread context.
7 Therefore, thread_B now attempts to run the remaining part of long running method on UI thread, while UI thread is waiting for thread_B to finish.
8 As UI thread and thread_B are waiting for each other, this creates the deadlock.
How to avoid deadlock?

In this case, deadlock can be avoided by anyone of the following ways:

1- Use await keyword while calling long running method. This makes the button click event asynchronous also.

private async void button1_Click(object sender, EventArgs e)
{
  textBox1.Text = await LongRunningProcess();
}

2- Call ConfigureAwait(false), this will inform the run time that the remaining part of long running method doesn’t need to execute on the UI thread, it can continue running on the thread pool.

public async Task<string> LongRunningProcess()
{
  string txt = await Task.Run(() =>
    {
      System.Threading.Thread.Sleep(5000);
      return "results";
    }
  ).ConfigureAwait(false); //avoids the deadlock

  return txt;
}
Why thread contexts are synchronized?

Consider the UI Controls (Windows Forms or WPF), they are not thread safe. Therefore, any update to the UI controls must be done only from the UI thread. To take care of this, any remaining code after await keyword in an asynchronous method will also execute on the thread context which initiated the method call.

Similarly, in an ASP.Net application, running the code on same thread context is important because the Culture, Principal and other information of the request are stored in the thread.

How thread contexts are synchronized?

To manage all this tricky context synchronization, we have SynchronizationContext class in .Net. There are framework specific implementations (derived classes) for Windows Forms, WPF/Silverlight and ASP.Net which handle the SynchronizationContext in their own ways for the framework to function properly.

The Windows Forms implementation uses Control.Invoke method to accomplish this (more details here). For ASP.NET, execution takes place on a different thread but the context is captured and passed on to the new thread.

There is an excellent article on MSDN regarding the SynchronizationContext which I recommend for details.

 

Creating and Consuming Async methods (C# .Net)

The code we want to run asynchronously could either be CPU-bound or IO-bound. CPU-bound code keeps the CPU busy, requiring intensive processing, calculations etc. On the other hand, IO-bound code frees up the CPU while waiting for an IO operation to complete, for instance, get some data from a web service. Both kinds of asynchronous methods are illustrated below.

 

 Creating Asynchronous method

 

CPU-bound Async method
public async Task<string> OurMethodAsync()
{
  string x = await Task.Run(() =>
    {
      // performs CPU intensive work
      return LongRunningTask();
    });

  return x;
}

Above method doesn’t do anything special. Rather than performing the work itself, it creates a thread and delegates the work to it. It will not make the task run faster, in fact, it may take more time due to multi-threading overhead. One reason to do things this way is to free the calling thread and not keep it busy for long time. This is required in case of User Interface threads, for instance.

 

IO-Bound Async method

For IO operation such as working with file system, requests to web servers etc., .Net framework already provides us with methods which run asynchronously. These methods uses lower levels OS calls to provide asynchronous behavior for blocking IO operations.

Below is our asynchronous method which uses .Net Framework’s WebClient.DownloadStringTaskAsync method.

public async Task<string> GetWebPage(string url)
{
  var webClient = new WebClient();
  string txt = await webClient.DownloadStringTaskAsync(url);

  return txt;
}

 

 Consuming asynchronous method

 

Consuming asynchronous method with await
private async void button1_Click(object sender, EventArgs e)
{
  textBox1.Text = await GetWebPage("http://www.yahoo.com");
}

 

This button click event consumes the IO-bound async method defined above. If GetWebPage method is taking a long time, the control will return back to the caller method. Once results of GetWebPage are available, execution will start again with the instruction after await keyword. This will ensure that the event does not block the UI thread.

Calling asynchronous methods concurrently

We can also use asynchronous method to run tasks in parallel.

private async void button1_Click(object sender, EventArgs e)
{
  Task<string> task1 = GetWebPage("http://www.yahoo.com");
  Task<string> task2 = GetWebPage("http://www.google.com");

  await Task.WhenAll(task1, task2);

  textBox1.Text = task1.Result;
  textBox2.Text = task2.Result;
}

 

Notice we are not using await keyword now when invoking GetWebPage method. This causes the return type to change also, we are expecting Task rather than string object.

The flow control is also very different. If GetWebPage is blocking, the control doesn’t return to the caller method, rather execution continues to the next statement in the event.

We have await in the third line which will relinquish control to the caller method if task1 or task2 are not completed yet. When the result of the two tasks are available the last two lines of code are executed on the UI thread.

Keeping UI Responsive (C# .Net)

The User Interface (UI) becomes unresponsive when a time taking operation is executed during an event.

Consider the following button click event where I have simulated a time taking operation by calling Sleep method. In a real scenario, it could be some processing which produces the result to be shown back on the user interface.

private void button1_Click(object sender, EventArgs e)
{
   textBox1.Text = "Calculating result…";
   // long running operation simulated through Thread.Sleep
   System.Threading.Thread.Sleep(5000);

   textBox2.Text = "Final result";
}

 

Keeping UI responsive through System.Threading.Tasks.Task

To keep the UI responsive, we can spawn a new thread to perform the time taking operation. Earlier, we used to do it with System.Threading.Thread but now we have more convenient Task class from TPL (Task Parallel Library) in .Net.

private void button1_Click(object sender, EventArgs e)
{
   // do initial UI update
   textBox1.Text = "Calculating result…";

   // spawn a new thread for the long running operation and final UI update
   Task.Run(() =>
      {
         System.Threading.Thread.Sleep(5000);
         // unsafe call to UI control
         textBox2.Text = "Final result";
      });
}

 

If we run the above code in debug mode, we get the following exception:

image

UI controls are not thread-safe, therefore, call to the UI should only be made from UI thread which created these controls.

The way around this problem is to use Invoke method of the control and pass it a delegate which performs the required UI changes. Invoke method will ensure that the delegate is executed on the UI thread.

private void button1_Click(object sender, EventArgs e)
{
   textBox1.Text = "Calculating result…";

   Task.Run(() =>
   {
      System.Threading.Thread.Sleep(5000);

      // using Control.Invoke
      Action act = () => textBox2.Text = "Final result";
      textBox2.Invoke(act);
   });
}

This will keep the UI responsive in a thread safe way.

 

Keeping UI responsive using async / await

Another way of doing this is through async / await keywords.

private async void button1_Click(object sender, EventArgs e)
{
   textBox1.Text = "Started";

   await Task.Run(() => System.Threading.Thread.Sleep(5000));

   textBox2.Text = "Final result";
}

 

This code will achieve the same results as above.

With async / await, the code looks more synchronous and readable. As await keyword is encountered, a new thread is started for processing the task and the method returns the control back to the caller (this ensures that the UI thread is free and responsive). Once the task is completed, rest of the code for the click event is executed on the UI thread. Behind the scene, compiler generates complex state machine logic to make this happen seamlessly.