SAP BusinessObjects Universe: Using ANSI92 SQL syntax

When writing SQL queries, I prefer the JOIN clause syntax over (+) in where clause for creating table joins. It is more readable and maintainable as join logic is separated from the where clause.

BusinessObjects Universe can be configured to generate JOIN clause (ANSI92) syntax by setting a parameter in ‘Universe Parameters’ dialog available from File menu.

 

image

 

We get some extra benefits by using ANSI92 syntax, for instance:

Full Outer Join

The functionality to define Full Outer join is available with ANSI92 syntax only.

image

Advanced Join Properties

The Advanced Join Properties give additional control over the generation of SQL queries from the universe. It determines whether a conditional expression should be included in where clause or join/on clause. These options are only supported with ANSI92 syntax.

image

 

The above applies to ‘Universe Design Tool’ version 14.0.7.  More at Official SAP BusinessObjects Universe Design Tool Guide.

BusinessObjects Universe: Defining Complex Outer Join

A complex join contains more than one condition in the join expression. Consider the following expression where one line of sales order joins with a line on invoice,

INVOICE_LINE.ORDER_NUM=ORDER_LINE.ORDER_NUM
and INVOICE_LINE.ORDER_LINE_NUM=ORDER_LINE.ORDERLINENUM

If we define a complex join in BusinessObjects Universe Design Tool, than the option to make it outer becomes disabled.

clip_image002

There are three possible ways to get around this problem (that I found), which are described below.

 

1) Create two separate joins

Create two separate joins to split the complex expression into simple ones. This will enable the ‘Outer join’ check box. While creating the query, the universe will automatically combine the two joins into one complex expression.

clip_image006

 

2) Set the Outer Join first, then specify complex expression (ANSI92 only)

Change the expression to simple temporarily; this will enable the ‘Outer join’ checkbox. Select the ‘Outer join’ and change the join expression back to the designed complex expression. Universe Designer will not only remember that ‘Outer join’ flag but also generate the right query at runtime with outer join clause.

Note: This solution only works if ANSI92 parameter is set to ‘Yes’. That is, join/on clause syntax is used for creating SQL query.

clip_image004

The universe will generate SQL similar to the following:


SELECT DISTINCT
INVOICE_LINE.INVOICE_NUM,
INVOICE_LINE.INVOICE_LINE_NUM,
ORDER_LINE.ORDER_NUM,
ORDER_LINE.ORDERLINENUM
FROM
ORDER_LINE RIGHT
OUTER JOIN INVOICE_LINE
ON (INVOICE_LINE.ORDER_NUM=ORDER_LINE.ORDER_NUM(+)
and INVOICE_LINE.ORDER_LINE_NUM=ORDER_LINE.ORDERLINENUM(+))

 

3) Directly specifying the complex expression with (+) syntax

We can directly specify the complex join expression and make it outer by using (+) syntax. Off course, this will only work when ANSI92 parameter is set to ‘No’.

clip_image008

Generated SQL will be something like:


SELECT DISTINCT
INVOICE_LINE.INVOICE_NUM,
INVOICE_LINE.INVOICE_LINE_NUM,
ORDER_LINE.ORDER_NUM,
ORDER_LINE.ORDERLINENUM
FROM
INVOICE_LINE,
ORDER_LINE
WHERE
( INVOICE_LINE.ORDER_NUM=ORDER_LINE.ORDER_NUM(+)
and INVOICE_LINE.ORDER_LINE_NUM=ORDER_LINE.ORDERLINENUM(+) )

 

The above applies to ‘Universe Design Tool’ version 14.0.7.  More at Official SAP BusinessObjects Universe Design Tool Guide

Designing BusinessObjects Universe: Join problems in schema and resolution techniques

An essential aspect of creating a BusinessObjects universe is to define joins among tables in ‘Universe Design Tool’. Even if the joins are correctly defined from relational point of view, the universe might not generate the correct results in certain cases. There are few pitfalls to avoid which are specific to the business of designing universe.  These pitfalls, generally referred as join problems, come in three major varieties: loops, chasm traps and fan traps.

Loop

Loop is the existence of more than one join paths between two tables. In other words, if we move among tables following joins and we can reach back to the original table using a different path, then we have a loop.

Loops will cause less number of records to be returned than expected.

BO Universe Loop

The Universe Design Tool can automatically detect loops and suggest solutions (aliases and contexts).

Chasm Trap

We are in Chasm Trap when a table joins with two others in one-to-may relationship. Learn more about them here.

Chasm Trap

 

Fan Trap

Fan trap is a less severe problem than other two. It does *not* affect the number of records returned  from the query, rather it affects the aggregation of an attribute.

Consider, an invoice record with three lines. While summing invoice total if it gets accounted thrice (once for each invoice line), than we are in Fan Trap.

Fan Trap

Techniques for resolving join problems

As universe designer, the toolbox consists of following to overcome the join problems:

Alias

A table can be duplicated in schema by giving it an alias (Both table and its alias refers to the same underlying table in database). This is the most common way to resolve join problems. Use of an alias can break loops or undesirable join paths.

Contexts

Context is a set of joins. It divides the universe in overlapping sets of tables and joins. If your table is part of more than one context, the report designer tool might ask the user to select the context if it can’t be inferred.

Self Restricting Join

Join can be defined as condition on a single table that limits the records returned from it. Such a join (which is not actually a join at all) is called Self Restricting Join.

Derived Table

Derived Table is like a database view. It allows us to create new tables in Universe based on a SQL query.

Shortcut Join

As the name says, it is shortcut to a longer join path. It is important to identify a shortcut join, otherwise we may have a loop.

Techniques to avoid

Joins could potentially cause issues which might motivate us to do without them, for instance, we can have sub-query in select clause to fetch data from another table. This is not recommended as query generated by universe might group by columns, in such a case query will not be valid.

So, the general rule is not to have sub-queries in select clause.

 

The above applies to ‘Universe Design Tool’ version 14.0.7.  More at Official SAP BusinessObjects Universe Design Tool Guide

Chasm Trap: Designing SAP BusinessObjects Universe

While designing SAP BusinessObjects universe with Universe Design Tool, Chasm Trap is one of the major join problems that one can come across.

We are in Chasm Trap when a table joins with two others in one-to-many relationship. Chasm Trap produces more data than expected.

Example

Consider the following ER diagram where DEPARTMENT is having 1-to-many relationships with EMPLOYEE and CONTRACT_STAFF tables.

Let’s assume we have following data in these tables.

image

BusinessObjects universe will produce something similar to the following query to join the above 3 tables:

select depart_name, employee_name, name "contract staff"
from department d
  inner join employee e on d.department_no = e.department_no
  inner join contract_staff c on c.department_no = d.department_no

Result of the query will have more rows than expected.

image

Resolution

Universe Design Tool doesn’t detect chasm traps automatically. They can be identified by visually inspecting the ER diagram.

Using Contexts

The recommended way of resolving Chasm Trap is to use contexts which will separate the two tables into separate contexts (employee and contract_stafff in our case). If both tables are used in the report, separate queries will be generated resulting in two tables in Web Intelligence report.

Using Derived Tables

Another approach which I have found handy in many cases is to use Derived Table functionality. Derived Table in universe designer can merge the two tables into one. Additional column containing record type can be introduced to still be able to tell the records apart (in our case, record type would be employee or contract_staff). This simplifies the design and avoids the Chasm Trap.

More at Official SAP BusinessObjects Universe Design Tool Guide

Git Push error: refusing to update checked out branch (Source Control)

Recently, I cloned a repository on my machine and made some changes to it. As I was pushing my changes back to the original repo, push failed with the error message:

“refusing to update checked out branch: refs/heads/master. By default, updating the current branch in a non-bare repository is denied…”

There are two things to note here in the error message. First the original repo is non-bare, secondly the push is to a branch which is currently checked out. Following are two possible ways to overcome the issue relating to bare repos and currently checked out branch.

Set Repository as ‘Bare’

Bare repositories do not have any working copy. Changes are not done directly to these repositories, rather changes are pushed from clones. Repositories hosted at GitHub are of this type.

One way to resolve the above issue is to make the repository ‘bare’. This can be done by running below command in original repo folder:

git config –bool core.bare true
 

Change the checked out branch

If you don’t want to convert your original repository to bare, another option is change the current branch. This can be done by:

git checkout
 

In case, there is only one branch in the repository, a temporary branch could be created and checked out:

git checkout -b temp
 

Once the push is executed, run the following commands to bring things back to original state:

git checkout master
git branch -d temp
 

Above will delete the temporary branch and checkout the master branch.

More at http://stackoverflow.com/questions/11117823/git-push-error-refusing-to-update-checked-out-branch

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.