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.

Book Review: Operational Decision Management for Dummies

ODM for Dummies BookBusiness rules and validations related to an automated Business Process are generally hidden deep within the application source code and configuration settings. They are not openly accessible, easily to change or review. They might be duplicated several times across the source code.

Operational Decision Management (ODM) systems try to remedy this situation by providing a central repository for business rules. This repository acts as a single source of truth for users as well as systems. Rules are generally specified in the form of Decision Tables or Trees.

ODM complements BPM (Business Process Management) systems well, as BPM is also metadata driven with a focus on business process workflows and SOA (Serice Oriented Architecture) for integration.

Operational Decision Management for Dummies is a free booklet sponsored by IBM which provides a nice and quick definition of ODM systems. It is recommended for anyone interested in understanding what ODM is, what are its use cases and potential pay offs.

You can also check out this article for some concrete examples on how operational decisions (business rules) are automated by any ODM system.

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‘.

 

Completed ‘Søren Kierkegaard – Subjectivity, Irony and the Crisis of Modernity’ from Coursera

Completed ‘Søren Kierkegaard – Subjectivity, Irony and the Crisis of Modernity‘ course taught by Associate Professor Jon Stewart from University of Copenhagen. The course is offered through Coursera platform and ran for 8 weeks from 6st October 2014 through 1st December 2014.

Course consisted of weekly reading assignments from the works of Kierkegaard, followed by video lectures where Professor Jon provided the background of the text and explained the key points. Video lectures are shot at various locations in Copenhagen which are associated with the life of Kierkegaard. The course concluded with an assignment to write a shot essay on a given topic related to Kierkegaard’s ideas.

My essay was on ‘What did Kierkegaard learn from his study of Socrates? Why is this connection between Socrates and Kierkegaard still relevant in the world today?’.

Coursera Soren Kierkegaard Certificate

What did Kierkegaard learn from his study of Socrates? Why is this connection between Socrates and Kierkegaard still relevant in the world today?

I wrote the following piece as part of an assignment for online course on Kierkegaard from Coursera.

…..

Kierkegaard believes from his study that Socrates has a distinct methodology for teaching his audiences through his dialogues. This method of Socrates has a profound wisdom where it focuses on preparing his interlocutor for accepting and realizing the truth, rather than directly confronting him with it.

Socrates uses Irony to show contradictions in beliefs of his contemporaries. As Socrates engages in dialogue with a person, he praises his interlocutor and acknowledges his wisdom and social stature. He expresses the desire and willingness to learn from him and claims that he ignorant on the subject. The dialogue starts with Socrates asking questions and getting involved in an argument. As Socrates asks deeper questions or points out contradictions, the interlocutor finds him at a loss to answer. This bring about a realization that some of our deeply held beliefs cannot be defended so easily and may be questioned.

At this point, when the interlocutor cannot defend his position, Socrates doesn’t offer his own position on the subject. Instead, he leaves the dialogue without any conclusion, in a state of Aporia. It is a state of puzzlement where a person actively engaged with a riddle is left on his own to solve it.

Socrates don’t confront his interlocutors with truth. Instead, he felt that the real task is to direct one towards a path where he can find the truth for himself. This is important as we already have the truth within ourselves, just it is needed to be brought out. In this sense, Socrates believed that his role was like a midwife whose only assists in bringing out. This characteristic of Socratic Method is called Maieutics (midwifery).

Socratic Method takes into account the subjective aspect of truth i.e. an individual should have an inward realization of truth to really grasp it. It requires an effort, a journey on part of the seeker. Truth, rather than just being told or accepted based on some authority, should also be internalized. This does not mean that Socrates was a relativist, he was against Sophist who were the relativist of his time. He believed in the objectivity of truth but also acknowledged that it has a subjective aspect.

Socrates’s teachings are negative in the sense that they tear apart arguments and beliefs of his interlocutors. In this regard, Kierkegaard argues that Socrates’s teaching are completely negative and he doesn’t offer anything positive at all. For Kierkegaard, as opposed to Hegel, this shall not be taken as a deficiency in Socrates’s approach. It is due to the wisdom of Socrates that he never offers any positive doctrine but instead plays the role of a midwife. He assists the person in his journey to bring out the truth which he already have within himself.

Kierkegaard is deeply influenced by this Socratic Method and tries to follow this model throughout his scholarly career. This theme can be seen in all his works where Socrates and his wisdom props up from time to time.

. . . . .

Kierkegaard has influenced many later philosophers and thinkers, especially in our times. His ideas have been part of, and a source of inspiration for leading philosophical movements of 20th century like existentialism and post-modernism. His philosophy is still relevant as he was a highly original thinker and was one of first to perceive and predict the problems of modern era. It is difficult to classify him as being part of any of the modern philosophical movements, because he never attempted a systematic exposition of his views. Rather his writings shake and stimulate the reader to look for the truth which he can appropriate and which can become the purpose of his life.

Modern man suffers from the loss of moral innocence and a lack of meaning. There is a widespread feeling of alienation as old social structures give way to the modern way of life. Kierkegaard with his Socratic teaching is pertinent to this modern condition, it encourages us to question the excesses of our times and emphasizes the need to understand and appropriate truth for one’s self. The value of truth is not in the cogent set of arguments which prove its validity, its power lies in the giving us a purpose and making our life meaningful.

Kierkegaard died in 1855 but his ideas are still with us with the power to strike a chord within our heart and make our existence worth it.

 

Completed SAP BusinessObjects course on ‘BI Clients and Applications’ from openSAP

BI Clients and Applications - Record of Accomplishment

This is my first openSAP course where I managed to stick around till the end. Generally I found the content on openSAP to be a bit dull. At times it seems that you watching a marketing video rather an educational one. Anyway, there is a lot of useful content also.

This six-week online course was held from October 29 through December 17, 2014. Following topics were covered:

  • SAP HANA as an Analytics Platform
  • Self-Service
  • Dashboards and Applications
  • Semantic Layer and Reporting
  • Mobility and Cloud
  • User Experience Tools and Features

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.

 

 

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