Microsoft Visual Studio LightSwitch 2011 Released

by Mark Zhou 26. July 2011 22:34

July 26th, 2011 (PST) – Visual Studio LightSwitch 2011 is released! Visual Studio LightSwitch 2011 provides a simple way to create line of business applications, with less code and much designer experience. During the 1+ year beta period. Visual Studio LightSwitch gained a bunch of good reviews, many developers has started, or prepare to start developing their applications targeting to the new platform that is the new member of the Visual Studio product family.

Now the good news is if you’re an MSDN Subscriber, you can download the Visual Studio LightSwitch 2011 x86 DVD via MSDN Subscription website; or you’re not – download the public trial web installer from the public Microsoft Download Center website.

PS: An interesting thing in the public download page, saying the LightSwitch 2011 is not available in China… Microsoft is hard working on resolving this issue, hope Microsoft also work to solve the GFW issue as well…

Untitled

Enjoy! Smile

Tags:

Visual Studio

Use dynamic type in Entity Framework 4.1 SqlQuery() method

by Mark Zhou 2. June 2011 02:27

As the release of Entity Framework 4.1, the DbContext.Database.SqlQuery() method offers a way to execute a SQL command then maps the returning result set to a strong typed object or a list of strong typed objects. However, if you want to use the dynamic type or anonymous type as its return type, you will probably get your code compiled but receive exceptions during runtime.

The reason is that the Entity Framework does the type mapping using Reflection. Additionally, Entity Framework searches each property on your returning type, and do mapping by matching the property name and the SQL returning column name, if your type doesn’t have any public property (public fields don’t work) defined, there will be no mappings happen.

To use the dynamic type on SqlQuery method, you must find a way to dynamically construct a type, then add property definitions to this type. To do so, you will be required to use Reflection Emit technology.

Reflection Emit is a way to runtime inject IL code into a specified AppDomain. By using Emit, you can actually create dynamic assemblies, modules or types on any AppDomain in your application. The following Console application illustrates how to use Reflection Emit to use dynamic as returning types of SqlQuery method.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Collections;
using System.Reflection.Emit;
using
System.Reflection;

namespace
Demo
{
   
public class Program
    {
       
public static void Main(string
[] args)
        {
           
string connectionString = "Server=(local); Integrated Security=true; Database=master"
;
           
using (DbContext context = new DbContext
(connectionString))
            {
               
TypeBuilder builder = Program.CreateTypeBuilder(
"MyDynamicAssembly", "MyModule", "MyType"
);
               
Program.CreateAutoImplementedProperty(builder, "name", typeof(string
));
               
Program.CreateAutoImplementedProperty(builder, "type", typeof(string
));
               
Program.CreateAutoImplementedProperty(builder, "id", typeof(int
));

               
Type
resultType = builder.CreateType();

               
dynamic queryResult = context.Database.SqlQuery(
resultType,
"SELECT * FROM sys.sysobjects"
);

               
Console.WriteLine("{0,20} {1,4} {2,10}", "Name", "Type", "ID"
);
               
foreach (dynamic item in
queryResult)
                {
                   
Console.WriteLine("{0,10} {1,4} {2,10}"
, item.name, item.type, item.id);
                }
            }

           
Console
.ReadKey();
        }

       
public static TypeBuilder CreateTypeBuilder(
string assemblyName, string moduleName, string
typeName)
        {
           
TypeBuilder typeBuilder = AppDomain
.CurrentDomain
.DefineDynamicAssembly(
new AssemblyName(assemblyName), AssemblyBuilderAccess.Run)
.DefineDynamicModule(moduleName)
.DefineType(typeName,
TypeAttributes
.Public);
            typeBuilder.DefineDefaultConstructor(
MethodAttributes
.Public);
           
return
typeBuilder;
        }

       
public static void CreateAutoImplementedProperty(
TypeBuilder builder, string propertyName, Type
propertyType)
        {
           
const string PrivateFieldPrefix = "m_"
;
           
const string GetterPrefix = "get_"
;
           
const string SetterPrefix = "set_"
;

           
// Generate the field.
            FieldBuilder fieldBuilder = builder.DefineField(
string.Concat(PrivateFieldPrefix, propertyName), propertyType, FieldAttributes
.Private);

           
// Generate the property
            PropertyBuilder propertyBuilder = builder.DefineProperty(
propertyName,
PropertyAttributes.HasDefault, propertyType, null
);

           
// Property getter and setter attributes.
            MethodAttributes propertyMethodAttributes =
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes
.HideBySig;

           
// Define the getter method.
            MethodBuilder getterMethod = builder.DefineMethod(
string.Concat(GetterPrefix, propertyName),
propertyMethodAttributes, propertyType,
Type
.EmptyTypes);

           
// Emit the IL code.
            // ldarg.0
            // ldfld,_field
            // ret
            ILGenerator
getterILCode = getterMethod.GetILGenerator();
            getterILCode.Emit(
OpCodes
.Ldarg_0);
            getterILCode.Emit(
OpCodes
.Ldfld, fieldBuilder);
            getterILCode.Emit(
OpCodes
.Ret);

           
// Define the setter method.
            MethodBuilder setterMethod = builder.DefineMethod(
string.Concat(SetterPrefix, propertyName),
propertyMethodAttributes,
null, new Type
[] { propertyType });

           
// Emit the IL code.
            // ldarg.0
            // ldarg.1
            // stfld,_field
            // ret
            ILGenerator
setterILCode = setterMethod.GetILGenerator();
            setterILCode.Emit(
OpCodes
.Ldarg_0);
            setterILCode.Emit(
OpCodes
.Ldarg_1);
            setterILCode.Emit(
OpCodes
.Stfld, fieldBuilder);
            setterILCode.Emit(
OpCodes.Ret);

            propertyBuilder.SetGetMethod(getterMethod);
            propertyBuilder.SetSetMethod(setterMethod);
        }
    }
}

The anonymous types may not work as well because there is no default constructor for anonymous types. Hope this helps.

Tags: ,

Entity Framework

Visual Studio 1st Anniversary, New stuff to collect!

by Mark Zhou 12. April 2011 20:08

Today, April 12th, 2011 (PST) is the first anniversary of the release of Visual Studio 2010. Microsoft has prepared some cool stuff for developers to collect for celebrate. In this post, I will share you what the new stuff is waiting for you as special gifts and offers.

UPDATED April 13th, 2011 PST, MIX’11 2nd Day

Silverlight 5 Beta

Silverlight 5 Beta brings new features: more than 1,500 new APIs, hardware acceleration support, double click support, real operating system window and significant performance improvements.  This Beta version also includes a refresh release of the WCF RIA Service 1.0 SP2 Preview, Interested users can now download the Silverlight 5 Beta Tools for the Visual Studio 2010 SP1. Note that you cannot install this tool with Visual Studio 2010 RTM, it requires SP1 to work.

Visual Studio Async CTP SP 1 Refresh (Supports for Visual Studio 2010 SP1)

The next version of C# and Visual Basic will provide a new way to program with the asynchronous model. This refresh release provides updated compilers, assemblies and tools to use the new TPL-based asynchronous pattern. This release supports Visual Studio 2010 SP1. You can download it from here, you can also find the C# Language Specification and Visual Basic Language Specification for the Async CTP on MSDN.

I also blogged some articles about the new async pattern. Please refer to the following articles to learn more.

and there is a new Task Parallel Library Data Flow preview to evaluate.

**** END UPDATE ****

ADO.NET Entity Framework 4.1 RTM

Last month, Microsoft released the Release Candidate (RC) of the ADO.NET Entity Framework 4.1, and promised to announce the RTM in this month. Now, ADO.NET Entity Framework 4.1 is ready for download. This release brings the new DbContext API with Code First modeling feature for Entity Framework. So far I don’t know whether this release includes the support of enum types, which is a widely requested feature in the community; what I can know from the Release Notes is that the mapping to stored procedure is still not supported, but you can use an alternative way to direct call it through DbContext objects.

Visual Studio Power Tools

If you have not yet installed Visual Studio Power Tools, I encourage you to install it. Visual Studio Power Tools is a superset of utilities and enhancements for Visual Studio, including paste as HTML (very useful for writing blog or presentations), current line highlighting, well-organized tabs, auto-completion for braces, quick find (new), solution navigator etc. The latest version is 10.0.20318.14.

To install it, open your Visual Studio, click Tools, Extension Manager, then go to Online Gallery, as shown below.

image

Windows Azure Special Offers for MSDN Ultimate – Save $3,100 annually

Since April 12th, 2011, a new subscription plan for MSDN Ultimate (VL or retail) subscribers is available. The new plan offers:

  • 1,500 hours computing time
  • 30 GB storage
  • 5 SQL Azure database
  • 500,000 Access Control transactions
  • 5 Service Bus connection (1 pack)
  • 35 GB in, 35 GB out worldwide

The monthly usage excesses in the quota listed will be charged with MSDN Ultimate rate plan.

If you still not activate your MSDN Ultimate benefit for Windows Azure, please go to MSDN, sign in with your subscription account, go to My Account then click Windows Azure Platform.

image

After you complete the 3 easy steps, you will see a new subscription plan in your Microsoft Online Customer Portal.

image

NOTE: This offer is also available for BizSpark members.

Visual Studio Feature Packs

There are also some cool feature packs available for Visual Studio 2010.

  • Visual Studio Feature Pack 2
  • Visual Studio Load Test Pack
  • Visual Studio Lab Management Pack
  • Visual Studio Team Foundation Server with Project Server Integration

Check out these packs on the Visual Studio Feature Packs page on MSDN.

Happy Birthday to Visual Studio 2010!

(This post refers the content from SomaSegar’s Weblog. for a whole list of the gifts and offers, please visit the blog here. )

Tags:

Visual Studio

Events should not have before or after prefix (CA1713, Microsoft.Naming)

by Mark Zhou 6. December 2010 19:57

An event represents a signal that causes to raise a specified action. For example, when you feel hungry, you will find something to eat. In this case, you can call Hungry an event, and call Eat() an action; as well, the Eat() is called the Event Handler, which will be used to handle things while the event is raised.

As the event is just a signal, or what we called a descriptor, there is a because-therefore relationship between event and event handler, raise an event is specifically happening on the point of a time, hence, most of the events represent present status. To name an event correctly and accurately, it is highly recommended that you use the general form of a verb or a verb phrase. For example, Click, DoWork, Load, Show, SaveControlState and KeyPress.

However, you may also name an event with a post tense form of a verb or a verb phrase to represent a specific sequence when raising an action. Like TextChanged, WorkItemCompleted, Connected, Initialized are kind of these forms.

But do not use “before” or “after” prefix as part of its name to describe the sequence. Event been raised on a point of time so it is most likely to be a present tense stuff, using the general form or the post form of a verb makes more sense. This is also defined in the common naming conventions. If you want to define events in pairs to exactly describe the sequence of a raising action, use present and post form; if you only want to define one event for a raising action, just use the general form or post form.

Here are some example that define events in pairs: the Closing and Closed events of a System.Windows.Forms.Form, the KeyDown, KeyUp and KeyPress events for keyboard strikes, and the PropertyChanging and PropertyChanged events for a data bind object.

Here are also examples that define events just once: the Click event of a System.Windows.Forms.Button, the DownloadDataCompleted event of a System.Net.WebClient, and the TextChanged event of a System.Windows.Controls.TextBox.

Do not suppress a warning message from this rule, to fix this warning, eliminate the “before” and “after” prefix from the name of event.

To get more information, please see the MSDN link for CA1713.

Tags: , , ,

Do not prefix enum values with type name (CA1712, Microsoft.Naming)

by Mark Zhou 28. November 2010 23:42

Many C/C++ merged C# developers is habitually to prefix the values for an enum with its type name, for example, in C/C++, all constants start with acronyms of two or more letters to indicate where and how they can be used. Like WM_CHAR is a constant where “WM” means “Windows Message” so that it can be used with SendMessage, GetMessage, PostMessage and TranslateMessage functions; similarly, GWL_STYLE is a constant representing the flag to get the basic styles for a window when you call GetWindowLong function. These prefixes make sense because for Windows, all constants are defined with #typedef directives and will be converted back to their original values once complied, constants are therefore weakly typed and there must be a way to distinguish these constants from the places and ways to use.

In C#, you can use enum to replace constant definitions. Enum is a primitive, strong type in .NET Framework to represent all enumeration elements such as WM_CHAR or GWL_STYLE. Enum is self-described, when refer to a value of a specified enum, the type name of that enum must be provided as well. Enum is strong typed to protect type safety, prevent conversions between different enum types directly so you will never get confused with the same value elements of different enum types. Because enum is self-described, the type name must exist when you refer an instance of an enum type, hence, prefix the enum values with type name is redundant, helpless and meaningless.

The following example shows the incorrect name convention for enum values, which contains prefix for its type name.

public enum TransactionMode
{
    TransactionModeCash,
    TransactionModeCreditCard,
    TransactionModeCheck,
    TransactionModeOther
}

The correct and recommended way to name the values show as following code.

public enum TransactionMode
{
    Cash,
    CreditCard,
    Check,
    Other
}

The type information of enum value is provided by developer tools, like Visual Studio IntelliSense.

Do not suppress a warning message from this rule in any case, try to avoid type name prefix when you are designing your enum types.

For more information, please see this MSDN link for CA1712.

Tags: , , ,

The SEQUENCE object in SQL Server codenamed “Denali”

by Mark Zhou 17. November 2010 23:42

The next generation of the SQL Server product, code named “Denali”, has announced some days ago. It has many functionality enhancements to help T-SQL programmers to deliver more efficient code. The SEQUENCE object is one of the new T-SQL built-in types that automatically generates sequential numbers in specific conditions and settings.

Create a SEQUENCE object

The new CREATE SEQUENCE statement can be used to create a database wide SEQUENCE object to use. The following code creates a SEQUENCE object on the default schema with a name MySeq.

USE TechTalk;
GO

-- Create a SEQUENCE object on schema "dbo".
CREATE SEQUENCE MySeq;
GO

-- Verify if the MySeq is created.
SELECT * FROM sys.sequences WHERE name = N'MySeq';

In the above example, I created a SEQUENCE object MySeq, of default type int, with default start value –2147483648 (the minimum value of a 32-bit signed integer) and auto-increment by 1. To check the next value of MySeq object, use NEXT VALUE FOR function, as shown below.

SELECT NEXT VALUE FOR MySeq;

In addition, to create a SEQUENCE object with an initial start value, an increment, and specify a integral type for this object, you can use the following code:

USE TechTalk;
GO

-- Create a SEQUENCE object on schema "dbo".
CREATE SEQUENCE MySeq AS tinyint
START WITH 0
INCREMENT BY 5;
GO

-- Verify if the MySeq is created.
SELECT * FROM sys.sequences WHERE name = N'MySeq';

-- Get the next value for MySeq.
SELECT NEXT VALUE FOR MySeq;
SELECT NEXT VALUE FOR MySeq;

When I run this code, I get the following result:

image

Note: the default start value for a SEQUENCE object is the min value of the type of that object, for example, if the SEQUENCE object is of type int, the default start value is -2147483648. To make code readable, it is highly suggested that you always specify the start value and the incremental value of a CREATE SEQUENCE statement.

Drop a SEQUENCE object

Similarly, you can use the DROP SEQUENCE statement to drop a SEQUENCE object, like I do as following:

USE TechTalk;
GO

-- Create a SEQUENCE object on schema "dbo" if not exist.
IF EXISTS (SELECT * FROM sys.sequences WHERE name = N'MySeq')
DROP SEQUENCE MySeq;
GO

CREATE SEQUENCE MySeq AS tinyint
START WITH 0
INCREMENT BY 5;
GO

Use SEQUENCE object

When created a SEQUENCE object, it is database wide, meaning different tables can access the same SEQUENCE object. This behavior is different as an IDENTIFY column – the last one can only be used in the table or view that defined it.

The following code shows the simple usage of SEQUENCE object MySeq defined by previous code.

-- Declare table variable.
DECLARE @contact TABLE
(
Id int NOT NULL PRIMARY KEY,
Name nvarchar(50) NOT NULL,
Age int NOT NULL
);

-- Insert values into this table.
INSERT @contact (Id, Name, Age)
VALUES 
(NEXT VALUE FOR MySeq, N'Mark Zhou', 27),
(NEXT VALUE FOR MySeq, N'Dixin Yan', 25),
(NEXT VALUE FOR MySeq, N'Wei Ye', 28);

-- Update the table.
UPDATE @contact
SET Id = NEXT VALUE FOR MySeq
WHERE Name = N'Mark Zhou';

-- Get the next value of MySeq.
DECLARE @nextValue int = NEXT VALUE FOR MySeq;

-- Use MySeq in different tables.
UPDATE @myTable
SET Id = NEXT VALUE FOR MySeq
FROM @contact AS c
WHERE c.Id = @nextValue;

Advanced Usages

1. Specify min and max value for a SEQUENCE object

To specify the minimum or maximum value for a SEQUENCE object, add MINVALUE or MAXVALUE directives in CREATE SEQUENCE statement. Note that the min value must less than or equal to start value, and both min and max values must in boundaries. For example, the min value cannot less than -2147483648 if the type of this SEQUENCE object is of 32-bit integer.

The following code shows how you can specify min or max value.

CREATE SEQUENCE MySeq AS tinyint
START WITH 0
INCREMENT BY 5
MINVALUE 0
MAXVALUE 255
GO

2. Specify whether a SEQUENCE object is cycled

If you turn this option on, when the next value exceeds the maximum value of the SEQUENCE object specified by the MAXVALUE directive, or the default max value of the SEQUENCE type, it will be restarted to the minimum value that specified by the MINVALUE directive, or the default min value of the SEQUENCE type, and vice versa if the INCREMENT BY directive specifies a negative integer value.

The following code shows how to turn cycling on.

CREATE SEQUENCE MySeq AS tinyint
START WITH 0
INCREMENT BY 5
MINVALUE 0
MAXVALUE 255
CYCLE;
GO

If you specify NO CYCLE, the cycling feature will be turned off. When it turned off, an exception will be thrown when the current value exceeds to the min or max value of the SEQUENCE.

3. Restart a SEQUENCE

To restart the current value of a SEQUENCE object to its initial or specified value, use ALTER SEQUENCE statement, as shown below:

ALTER SEQUENCE MySeq
RESTART;

To specify a restart value, use the following code:

ALTER SEQUENCE MySeq
RESTART WITH 10;

4. Use NEXT VALUE FOR with OVER clause

Combine the NEXT VALUE FOR function with OVER clause to sort the result set prior generate sequence numbers. The following example shows how to use it:

USE TechTalk;
GO

-- Create a SEQUENCE object on schema "dbo" if not exist.
IF EXISTS (SELECT * FROM sys.sequences WHERE name = N'MySeq')
DROP SEQUENCE MySeq;
GO

CREATE SEQUENCE MySeq AS tinyint
START WITH 1
INCREMENT BY 1
MINVALUE 1
NO MAXVALUE
CYCLE;
GO

-- Declare table variable.
DECLARE @score TABLE
(
Id int NOT NULL PRIMARY KEY,
Name nvarchar(50) NOT NULL,
Score int NOT NULL
);

-- Insert values into this table.
INSERT @score (Id, Name, Score)
VALUES 
(NEXT VALUE FOR MySeq, N'Mark Zhou', 90),
(NEXT VALUE FOR MySeq, N'Dixin Yan', 91),
(NEXT VALUE FOR MySeq, N'Wei Ye', 89);

SELECT Name, Score, NEXT VALUE FOR MySeq OVER (ORDER BY Name DESC)
FROm @score;

5. Get full information for a SEQUENCE object

Use the system view sys.sequences to retrieve all information about a SEQUENCE object, including the current value, type, is cycled, is cached, min value, max value, start value, incremental value and more.

This code retrieves all the created sequences:

SELECT * FROM sys.sequences

And results are shown as below:

image

The full CREATE SEQUENCE syntax

To get the full syntax for CREATE SEQUENCE statement, see this MSDN link.

Tags: ,

What are actually synchronous/asynchronous operations (C# 5.0 Series)

by Mark Zhou 15. November 2010 04:43

I have blogged two C# 5.0 articles, both are regarding the new Asynchronous Programming Model (APM); In these articles, I discussed the different APMs that can be used in .NET Framework, I also introduced the new syntactical sugar async and await, which simplifies the way to perform asynchronous operations. Many people aware the concept of synchronous and asynchronous operations, could somehow distinguish them, but however, there are also a lot of misunderstandings regarding these two, that most of the developers may confuse. In this article, I will clarify what are on earth synchronous and asynchronous operations.

There are many inaccurate explanations to these two concepts where you can find in computer technique sites everywhere in the web. Saying:

  1. Synchronization means two or more operations are running in a same context (thread) so that one may block another.
  2. Synchronization means two or more operations happen sequentially.
  3. Asynchronous means two or more operations are running in different context (thread) so that they can run concurrently and do not block each other.
  4. Asynchronous means two or more operations happen asynchronously.
  5. And more…

I would like to point out that both of them are inaccurate. See my discussion below.

1. Synchronous code may or may not run in the same thread.

As all know, synchronous operations may cause a block, but the root cause leading this block is resource contention, not the operation itself. Let’s say there are four people in a room, and the gate of that room can pass 2 people at a time, to get the four people out of the room, they can pass the gate one by one, or they can be grouped into two, then pass the gate by twice. In the first way, the four people pass the gate in a sequence, if the first person doesn’t get to the gate, the others cannot pass. In another word, if an operation in the sequence is not done, all remaining operations are blocked. The second way, which allows the four people pass the gate in less time, groups the four people into two, because each time the gate can pass two people, so to quickly pass the gate, we can let two people to pass at a time, in this scenario, each time there are two people passing the gate simultaneously, and we just need to do it twice in a sequence.

Converting this example to the computer words, a set of operations may access one resource, the resource can take several operations at one time, to access the resource, the operations can be performed sequentially, only one operation accesses the resource at one time, and this can be done within a same thread; alternatively, the operations can be grouped by the maximum number of operations that the resource can take, then performs the operations by group, in which the operations are performed simultaneously.

Thinking a bad case, if the gate is being maintained, to let the people get out of the room, they can either pass one by one, or pass by groups, but whatever options they choose, they cannot get out because now the gate is in a contention, some other operations (maintenance work) are taking on the gate, and other operations (gate passing) are blocked till the contention disappears (maintenance work is done). This causes a block, and the synchronization is required to avoid the contention. So it is obviously nothing to do with whether the operations run on a same thread or multiple threads. Only a contention on specific resource can cause a thread block, and then the synchronization code is desired for.

But what causes a contention on a specific resource? conceptually, more than one operations manipulate one resource simultaneously with isolated access (which means resource cannot be shared by multiple operations at the same time) causes a contention on that resource.

2. Synchronous operations can perform sequentially, or simultaneously.

As I just discussed, thread synchronization is required to avoid blocking, a block is caused by a contention, because contention is nothing to do with threads, the synchronous operations can perform in a same thread (sequentially), or in different thread (possible simultaneously). Here the “synchronous” means “already handled to avoid the thread block”, and doesn’t mean “the operations who can lead a contention”.

So what is actually synchronization? synchronization is the way to design the thread-safe code where can totally avoid the resource contention, make sure only one thread is accessing the resource at a time, and lead other threads waiting (blocked) for the resource till the accessing thread releases the resource. Synchronization neither mean performing actions at a same time, nor one by one, it just means design the code where it doesn’t cause a resource contention.

3. Asynchronous operations may or may not run in multithreads.

A synchronous operation may be blocked by other operations while they are accessing the same resource, in addition, if the proceeding logic of that synchronous operation doesn’t depend on the particular contented resource, the code will still not run because the current thread that running this synchronous operation is blocked entirely, causing the other code which irrelevant to that resource in the running thread wait till the synchronous operation finishes. This behavior blocks the other threads which attempt to access the contented resource, as well as blocks the continuing code in the thread itself to run. In most of the cases, it may lead the working application respond slower, or lose the response (this happens if the blocking thread is a UI thread).

As opposed to asynchronous operations, asynchronous operations perform “not-at-a-same-time” and run “somewhere” so that the current running thread is not blocked by it, specifically, when an operation that requires the access to a resource performs asynchronously, it will actually be scheduled to take “at some time later” and run “somewhere”, if the resource may cause a contention, and because that asynchronous operation runs “somewhere”, it will never block the current running thread so that the current running thread can handle other operations. In addition, because the asynchronous operation runs “somewhere”,  it will never be affected by the state of the current running thread, if the thread is blocked by a synchronous operation, that asynchronous operation can keep running; if the asynchronous operation finishes with a return value, and meanwhile the running thread (who created the asynchronous operation) is not blocked, the thread can get this return value, and use it in another piece of code.

They are two points here, one is asynchronous operation runs “somewhere” and scheduled “at some time”. “Somewhere” often means “another thread”, but you can never say it is always “another thread”. The default implementation of a System.Threading.SynchronizationContext for Windows Forms application uses a mechanism that we called message loop to implement the asynchronous model in the same thread, which means the asynchronous operation could be run in the same thread who creates it, or in different threads. To get more information regarding this particular case, see Eric Lipper’s blog article: Asynchrony in C# 5.0 part Four: It's not magic.

4. Asynchronous operations can be just scheduled but never guaranteed to run at a certain time.

This is another point for the asynchrony: “at some time”. When starts an asynchronous operation, it will be scheduled to run as soon as possible; in my article The Asynchronous Programming Models (C# 5.0 Series), I discussed the task-based APM that requires a task scheduler implementation to schedule the asynchronous operations into different tasks, but however you get no way to know when exactly it will run. Hence, there is no prediction or indicator that can let us say these asynchronous operations will run simultaneously, or at different time. Asynchrony means “not-at-a-same-time”, but doesn’t mean “runs in background immediately”.

Please be noticed that all of the asynchronous operations can be just scheduled, the implementations of the task schedulers may decide where it to run (in same or different threads), when it to run (how the threads are dispatched to run the task as soon as possible) and how it to run (whether if this task will be split into small pieces that can be run in the same thread, same CPU, or multi-core CPUs); Don’t think asynchrony means “other threads”, “background”, “simultaneous” or “concurrent” – actually they are irrelevant.

At last, what is asynchrony? Asynchrony is a way to design the code where can avoid both resource contention and thread blocking, by putting the operation to a certain place, and scheduling the operation at some time to run. It neither means “running in different threads”, nor “doing things simultaneously”; it just a way to avoid thread blocking where manipulate the resource that may cause a contention.

Now making more sense?

Tags: , ,

Ad-hoc pagination support with SQL Server codenamed “Denali”

by Mark Zhou 10. November 2010 23:31

Microsoft has announced the first Community Technology Preview (CTP) of its next generation SQL Server product, codenamed “Denali” yesterday. SQL Server “Denali” has many new features and enhancements, including these for the programmability and manageability features which you may interest in:

  • Visual Studio 2010 based Management Studio tools
  • Advanced T-SQL debugging support
  • Code snippets and IntelliSense enhancements
  • Contained database
  • EXECUTE statement enhancements with RESULT SETS
  • OFFSET and FETCH sub-clause of ORDER BY clause
  • SEQUENCE objects
  • Enhancements to the geometry data types

To download SQL Server “Denali” CTP 1, please go to this page in Microsoft Download Center. http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6a04f16f-f6be-4f92-9c92-f7e5677d91f9.

In this article, I will discuss the ad-hoc pagination support with SELECT, ORDER BY and OFFSET query.

The Problem

In a data-centric Web or Windows application, one of the developer’s common task is to seek for a result set from the database which meets the specified query conditions, then display the result set in the User Interface. Suppose the application targets to Windows Phone 7 platform, and the result set is large, the user interface may not have enough space to render all the data in this result set in a single frame, therefore, developer has to add a vertical scrollbar to the user interface so that the end user can scroll up or down to view the remaining data rows; in addition, if the result set is huge, the scrollbar may be very short, it takes user a long time to scroll down from the top to bottom, user may also have difficulties to find what he wants in this long list. In this case, the result set must be split into pages that makes the vertical scrollbar longer, so the application can be easy to navigate to the data that the user intended. By using paging, application can be easier to use and more responsible. This is called pagination.

Let’s say we are going to do pagination with a SQL Server database, before SQL Server “Denali”, there is no direct support for the pagination, alternatively, the following methods are commonly used in the community.

  1. Use TOP and EXCEPT
  2. Use ROW_NUMBER and OVER with Common Table Expression (CTE)

Use TOP and EXCEPT

The following T-SQL code shows how to use TOP and EXCEPT with a SELECT query to implement pagination.

USE TechTalk;
GO

-- The page number and the page size variables
-- for demo, I hardcoded them with initial values.
-- @pageNumber must greater than or equal to 1.
DECLARE @pageSize int = 10;
DECLARE @pageNumber int = 2;

SELECT TOP (@pageSize * @pageNumber) *
FROM dbo.[Event]
EXCEPT
SELECT TOP (@pageSize * (@pageNumber - 1)) *
FROM dbo.[Event];
GO

The algorithm is like this: the first part of SELECT TOP statement seeks for the data with size equals to @pageSize times @pageNumber. this selects all previous and current page data, then, use the EXCEPT projection to eliminate previous page data by using another SELECT TOP statement, with size equals to @pageSize times @pageNumber subtracts 1. The resulting set is the data start from (@pageSize * (@pageNumber – 1) + 1) and end with (@pageSize * @pageNumber).

When I run this code in SQL Server Management Studio, I get the following output:

image

Use ROW_NUMBER() and OVER with Common Table Expression

Actually, if the seeking table has a identity number for each row, the paging problem is no longer a big problem, because you can calculate the start and the end row number for a specified page number, then use a WHERE clause to filter the query.

To achieve this, SQL Server provides a ROW_NUMBER() function, which can be used to generate a dynamic row identity number (start from 1 and increment by 1); with a Common Table Expression, you can easily add this row number column temporarily to the seeking table result set, then, use WHERE clause to implement pagination.

The following T-SQL shows how to use ROW_NUMBER() to do pagination.

USE TechTalk;
GO

-- The page number and the page size variables
-- for demo, I hardcoded them with initial values.
-- @pageNumber must greater than or equal to 1.
DECLARE @pageSize int = 10;
DECLARE @pageNumber int = 2;

WITH TempEvent AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber
FROM dbo.[Event]
)
SELECT * FROM TempEvent
WHERE RowNumber BETWEEN (@pageSize * (@pageNumber - 1) + 1)
AND (@pageSize * @pageNumber)

When I run this code, I get the exact same result as the first example.

Use OFFSET and FETCH with ORDER BY clause

SQL Server “Denali” enhances ORDER BY clause by adding OFFSET and FETCH sub-clause to specify how many rows to skip to return and how many rows should be returned. The enhanced syntax for ORDER BY is:

ORDER BY order_by_expression
     [ COLLATE collation_name ]
     [ ASC | DESC ]
     [ ,...n ] [ <offset_fetch> ] <offset_fetch> ::= {    OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS }
     [
       FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression }
{ ROW | ROWS } ONLY
     ] }

The following T-SQL code shows the usage of the OFFSET and FETCH with ORDER BY to implement pagination.

USE TechTalk;
GO

-- The page number and the page size variables
-- for demo, I hardcoded them with initial values.
-- @pageNumber must greater than or equal to 1.
DECLARE @pageSize int = 10;
DECLARE @pageNumber int = 2;

SELECT *
FROM dbo.[Event]
ORDER BY CreatedTime DESC
OFFSET @pageSize * (@pageNumber - 1) ROWS
FETCH NEXT @pageSize ROWS ONLY;

When I run this code, I get the following output:

image

Now you have an extremely simple way to have paginations in your application!

Note: The ADO.NET Entity Framework, LINQ to SQL and LINQ to Object supports pagination by using Skip() and Take() extension methods. For the current Entity Framework and LINQ to SQL implementation, it is possible to generate T-SQL that use ROW_NUMBER() function, it won’t generate new OFFSET and FETCH T-SQL code until the Entity Framework and the LINQ to SQL providers take the change in a future version of .NET Framework. It is obviously to predict that in the coming .NET Framework 5.0 and the Entity Framework 5.0, the integrity of SQL Server “Denali” with them will play an important role as part of the ADO.NET data access techniques.

Tags: , ,

The Asynchronous Programming Models (C# 5.0 Series)

by Mark Zhou 9. November 2010 00:35

In previous article, I mentioned a new feature of C# 5.0 – the async and the await keywords. They are syntactical sugars that simplifies the construction of asynchronous operations code. When the C# compiler sees an await expression, it generates code that automatically invokes the expression asynchronously, then immediately return the control flow to the caller so the caller code can continue executing without block; after the asynchronous operation finished, the control flow will be forwarded to the code below the await expression and execute the code sequentially till an exit criteria is reached (the exit criteria may be: the end of a method, or an iteration of a loop, etc). I emphasize that the await keyword is only a  syntactical sugar, it is therefore an alternative that compiler generates the equivalent code rather than you manually write it. Before you can understand what the C# 5.0 does for you for async and await keywords, you should first understand how the Microsoft .NET Framework provides the asynchronous programming models (APM).

In .NET Framework, there are many ways to implement an asynchronous operation: by using thread, thread pool, BeginXxx and EndXxx methods, event based APM, or Task based APM. The first way, using thread is not recommended because creating a thread is very expensive*, and it requires many manual controls to work well, so I will skip this discussion; the second way, using thread pool, is the easiest and the most commonly used way to go; the BeginXxx and EndXxx methods declared in specified types provide the standard way to perform an asynchronous operation; the event based asynchronous programming model is less popular than BeginXxx and EndXxx methods, .NET Framework just provides a very small set of the types that support event based APM; the last one, Task based APM, is introduced in .NET Framework 4 and is a part of Task Parallel Library (TPL), it dispatches asynchronous operations based on a task scheduler, it also offers many features to extend the task parallelism. The default task scheduler is implemented by using thread pool, .NET Framework also provides task schedulers implemented by Synchronization Contexts, in addition, you can implement your own task schedulers and use it to work with tasks.

* Creating a thread needs about 1.5 MB memory space, Windows will also create many additional data structures to work with this thread, such as a Thread Environment Block (TEB), a user mode stack, and a kernel mode stack. Bringing new thread may also need thread context switching, which also hurts performance. So avoid creating additional threads as much as possible.

In this article, I will go through the different ways to perform asynchronous operation, and show examples to guide you to use both of them.

The Thread Pool APM

When you want to perform an asynchronous operation, it is easy to use thread pool to do so, by calling System.Threading.ThreadPool’s QueueUserWorkItem static method, passing an instance of WaitCallback delegate and optionally an instance of Object that represents the additional parameter to associate with the instance of WaitCallback. The following example shows how to use thread pool to queue asynchronous operations.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ApmDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // Define a WaitCallback instance.
            WaitCallback writeCallback = state => Console.WriteLine(state);

            // Queue user work items with ThreadPool.
            ThreadPool.QueueUserWorkItem(writeCallback, "This is the first line");
            ThreadPool.QueueUserWorkItem(writeCallback, "This is the second line");
            ThreadPool.QueueUserWorkItem(writeCallback, "This is the third line");

            Console.ReadKey();
        }
    }
}

In the above example, I initialized an instance of a WaitCallback instance by assigning a lambda expression as the delegate body, then called ThreadPool’s static method QueueUserWorkItem, passed this instance as the first parameter, and a string as its second parameter. When calling this method, the thread pool seeks for a free thread in the pool, associates the instance of the WaitCallback delegate to that thread, and dispatches this thread to execute the delegate at some time; if there is no free thread in the pool, the thread pool creates a new thread, associates the delegate instance, and then dispatches to execute at some time. I queued three user work items to the thread pool, by calling QueueUserWorkItem method for three times.

When I try to run this program, I may get the following output:

This is the first line
This is the second line
This is the third line

But sometimes I also get the following output:

This is the second line
This is the first line
This is the third line

Please note that the executing order of the queued user work items is unpredictable because there is no way to know when a thread in the thread pool is scheduled to execute the code. As shown above, the work items may complete in sequential, and it is also possible that the work items complete in reverse order. Therefore, do not write asynchronous code that relies on the execution order.

I highly recommended that you use the thread pool APM as much as possible, here are some reasons:

  1. Thread pool is managed automatically by the CLR. When you queue a user item to the thread pool, you never care which thread it will be associated and when it will be executed; the CLR handles everything for you – this pattern enables you to write easy-to-read,. straightforward and less buggy code.
  2. Thread pool manages threads wisely. When perform an asynchronous operation, CLR requires additional thread to perform this operation so the operation can take without blocking the current thread, but however, creating new thread is expensive, introducing new thread every time to serve a user work item is heavy and waste of resources. Thread pool manages a set of threads initially, when a user work item is queued, the thread pool adds this work item to a global work item list, then a CLR thread will check this global work item list, if it is not empty, this thread picks up a work item, and dedicates it to a free thread in the pool; if there is no free thread, the thread pool will then create a new thread, and dedicate it to this newly created thread. The thread pool always chooses to use as less thread as possible to serve all queued user work items. Hence, by using thread pool, CLR uses less system resources, makes the asynchronous operations scheduling effective and efficient.
  3. Thread pool has better performance. Thread pool mechanism guarantees that it can use maximum or configured CPU resources to server user work items. If you are running your program in a multi-core CPU environment, the thread pool initially creates threads which number is equal to the number of the installed CPUs in that environment; when scheduling a user work item, thread pool automatically balances the threads, and makes sure that every logical CPU core is used to serve the work items. This brings a flexibility to dispatch CPU resources and also helps to improve the whole system performance.

Though there are a lot of benefits using thread pool, there are also limits:

  1. Thread pool queues a user work item, and executes it at an uncertain time, when it finished processing a user item, there is no way for the caller code to know when it will complete, thus it is very difficult to write continuation code after this work item is completed. Specially, some operations, like read a number of bytes from a file stream, must get an notification when the operation is completed asynchronously, then the caller code can determine how many bytes it read from the file stream, and use these bytes to do other things.
  2. The ThreadPool’s QueueUserWorkItem method only takes a delegate that receives one parameter, if you code is designed to process more than one parameter, it is impossible to directly pass all the parameters to this method; instead, you may create additional data structure to wrap those parameter, then alternatively pass the wrapper type instance to the method. This reduces the readability and maintainability of your code.

To solve these problems, you may use the following standard way to perform asynchronous operations.

The Standard APM

The Framework Class Library (FCL) ships various types that have BeginXxx and EndXxx methods, these methods are designed to perform asynchronous operations. For example, the System.IO.FileStream type defines Read, BeginRead and EndRead methods, Read method is a synchronous method, it reads a number of bytes from a file stream synchronously; in other word, it won’t return until the read operation from the file stream is completed. The BeginRead and EndRead methods are pair, when calling BeginRead method, CLR queues this operation to the hardware device (in this case, the hard disk), and immediately return the control flow to the next line of code and then continue to execute; when the asynchronous read operation is completed by the hardware device, the device notifies the Windows kernel that the operation is completed, then the Windows kernel notifies CLR to execute a delegate which is specified as a parameter by calling BeginRead method, in this delegate, the code must call EndRead method so that the CLR can transit the number of bytes read from the buffer to the calling delegate, then the code can access the bytes read from the file stream.

here is what the Read, BeginRead and EndRead method signatures are defined.

public override IAsyncResult BeginRead(byte[] array, int offset, 
int numBytes, AsyncCallback userCallback, object stateObject);
public override int EndRead(IAsyncResult asyncResult);
public override int Read(byte[] array, int offset, int count);

Usually, The BeginXxx method have the same parameters with the Xxx method and two additional parameters: userCallback and stateObject. The userCallback is of type AsyncCallback, which takes one parameter of type IAsyncResult which brings additional information to this asynchronous operation; the stateObject parameter is the instance that you want to pass to the userCallback delegate, which can be accessed by AsyncState property defined on this delegate’s asyncResult argument.

The following code demonstrates how to use BeginXxx and EndXxx methods to perform asynchronous operations.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;

namespace ApmDemo
{
    internal class Program
    {
        private const string FilePath = @"c:\demo.dat";

        private static void Main(string[] args)
        {
            // Test async write bytes to the file stream.
            Program.TestWrite();

            // Wait operations to complete.
            Thread.Sleep(60000);
        }

        private static void TestWrite()
        {
            // Must specify FileOptions.Asynchronous otherwise the BeginXxx/EndXxx methods are
            // handled synchronously.
            FileStream fs = new FileStream(Program.FilePath, FileMode.OpenOrCreate,
                FileAccess.Write, FileShare.None, 8, FileOptions.Asynchronous);

            string content = "A quick brown fox jumps over the lazy dog";
            byte[] data = Encoding.Unicode.GetBytes(content);

            // Begins to write content to the file stream.
            Console.WriteLine("Begin to write");
            fs.BeginWrite(data, 0, data.Length, Program.OnWriteCompleted, fs);
            Console.WriteLine("Write queued");
        }

        private static void OnWriteCompleted(IAsyncResult asyncResult)
        {
            // End the async operation.
            FileStream fs = (FileStream)asyncResult.AsyncState;
            fs.EndWrite(asyncResult);

            // Close the file stream.
            fs.Close();
            Console.WriteLine("Write completed");

            // Test async read bytes from the file stream.
            Program.TestRead();
        }

        private static void TestRead()
        {
            // Must specify FileOptions.Asynchronous otherwise the BeginXxx/EndXxx methods are
            // handled synchronously.
            FileStream fs = new FileStream(Program.FilePath, FileMode.OpenOrCreate,
                FileAccess.Read, FileShare.None, 8, FileOptions.Asynchronous);

            byte[] data = new byte[1024];

            // Begins to read content to the file stream.
            Console.WriteLine("Begin to read");
            // Pass both Fs and data as async state object.
            fs.BeginRead(data, 0, data.Length, Program.OnReadCompleted, new { Stream = fs, Data = data });
            Console.WriteLine("Read queued");
        }

        private static void OnReadCompleted(IAsyncResult asyncResult)
        {
            dynamic state = asyncResult.AsyncState;

            // End read.
            int bytesRead = state.Stream.EndRead(asyncResult);

            // Get content.
            byte[] data = state.Data;
            string content = Encoding.Unicode.GetString(data, 0, bytesRead);
           
            // Display content and close stream.
            Console.WriteLine("Read completed. Content is: {0}", content);
            state.Stream.Close();
            Console.ReadKey();
        }
    }
}

This program tests asynchronous read/write operations from/to a specified file stream, by using BeginRead, EndRead, BeginWrite and EndWrite methods defined on System.IO.FileStream class. When I try to run this program, I get the following output:

image

Now you may already know how to use the standard way to perform an asynchronous operation by calling BeginXxx and EndXxx methods. In fact, this standard way supports many more features as I demonstrated here, such as cancellation, which I will discuss in later articles, and supporting cancellation is really a big plus of this pattern. By using this pattern, you can solve some problems I listed for the thread pool APM, and you can also have additional benefits which I summarize below.

  1. Supports continuation. When an asynchronous operation is completed, the userCallback delegate is invoked, so the caller code can perform other operations based on the result of this asynchronous operation.
  2. Supports I/O based asynchronous operations. The standard APM works with kernel objects to perform I/O based asynchronous operations. When an I/O based asynchronous operation is requested by calling the BeginXxx method, the CLR doesn’t introduce new thread pool thread to dedicate this task, instead, it uses a Windows kernel object to wait for the hardware I/O device to return (through its driver software) when it finishes the task. CLR just uses the hardware device drivers and kernel objects to perform I/O based asynchronous operations, no more managed resources are used to handle this case. hence, it actually improves the system performance by releasing CPU time slices and threads usage.
  3. Supports cancellation. When an asynchronous operation is triggered, user may cancel this operation by calling System.Threading.CancellationTokenSource’s Cancel method, I will introduce this class in the later articles.

But however, by using standard APM, your code becomes more complicated. That’s because all the task continuation happen outside of the calling context, for example, in the above read/write file stream example, the OnReadCompleted and the OnWriteCompleted are separate methods and invoked by a different thread than the current calling thread, this behavior may confuse developers, and therefore make your code logic not clear to understand.

Note: The async method and the await expressions bring a clear, logical and organized code structure to the asynchronous programming.

The Event-based APM

The Framework Class Library (FCL) also ships with some types that support event-based APM. For example, the System.Net.WebClient class defines a DownloadDataAsync method, and a DownloadDataCompleted event, by calling DownloadDataAsync method, CLR begins an asynchronous operation for downloading the data from a specified URL, when it is completed, the DownloadDataCompleted event will be fired, the argument e of type System.Net.DownloadDataCompletedEventArgs contains results and additional information of this operation. Here is the code demonstrates how to use event based APM to perform asynchronous operation.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Net;

namespace ApmDemo
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            WebClient wc = new WebClient();
            wc.DownloadDataAsync(new Uri("http://www.markzhou.com"));
            wc.DownloadDataCompleted += (s, e) => Console.WriteLine(Encoding.UTF8.GetString(e.Result));

            Console.ReadKey();
        }
    }
}

Actually it acts with the same effect as using BeginXxx and EndXxx methods, the difference is event-based APM is more close to the object model layer, you can ever use a designer and a property window to drag-drop the component to the user interface and then set the event handler through the property window, as opposed, standard APM doesn’t provide events to subscribe, this helps to improve the system performance because implementing events may require additional system resources.

There are very small set of types in FCL support event-based APM, personally, I suggest not use this pattern as much as possible, the event-based APM may suit for the application developers because they are component consumers,. not the component designers, and the designer supportability is not mandatory for the component designers (library developers).

The Task-based APM

Microsoft .NET Framework 4.0 introduces new Task Parallel Library (TPL) for parallel computing and asynchronous programming. The mainly used Task class, which defined in System.Threading.Tasks namespace, represents a user work item to complete, to use task based APM, you have to create a new instance of Task, or Task<T> class, passing an instance of Action  or Action<T> delegate as the first parameter of the constructor of Task or Task<T>, then, call the Task’s instance method Start, notifies the task scheduler to schedule this task as soon as possible.

The following code shows how to use task based APM to perform a compute-bound asynchronous operation.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Task based APM demo");
            Task t = new Task(() =>
            {
                Console.WriteLine("This test is output asynchronously");
            });
            t.Start();
            Console.WriteLine("Task started");
           
            // Wait task(s) to complete.
            Task.WaitAll(t);
        }
    }
}

If I run this program, I will get the following output:

image

Alternatively, if the task delegate returns a value, you can use Task<T> instead of Task, after the task is complete, you can query the result by Task<T>’s Result property. The following code shows how to use Task<T> to calculate the nth exponent to 2 (n is positive only).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Task based APM demo");
            Func<int, int> calc = (n) => { return 2 << (n - 1); };

            Task<int> t = new Task<int>(() =>
            {
                return calc(10);
            });

            t.Start();
            Console.WriteLine("Task started");
           
            // Wait task(s) to complete.
            // After t is complete, get the result.
            Task.WaitAll(t);
            Console.WriteLine(t.Result);
        }
    }
}

When I run this program, I get the following output:

image

The Task’s static method WaitAll waits all tasks specified in the parameter array synchronously, meaning that the current thread will be blocked till all the specified tasks are complete. If you don’t want to block the current thread, and you intend to do something after a certain task is complete, you may use the Task’s instance method ContinueWith, Here shows how to do continuation tasks in the following code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Task based APM demo");
            Func<int, int> calc = (n) => { return 2 << (n - 1); };

            Task<int> t = new Task<int>(() =>
            {
                return calc(10);
            });
           
            // Set a continuation operation.
            t.ContinueWith(task => { Console.WriteLine(task.Result); return task.Result; });
            t.Start();
            Console.WriteLine("Task started");
           
            // Wait for a user input to exit the program.
            Console.ReadKey();
        }
    }
}

The task based APM has many features, I list some of the important features below:

  1. You can specify TaskCreationOptions when creating a task, indicating how the task scheduler will schedule the task.
  2. You can specify a CancellationTokenSource when creating a task, indicating the associated cancellation token used to cancel a task.
  3. You can use ContinueWith, or ContinueWith<T> method to perform continuation tasks.
  4. You can wait all specified tasks to complete synchronously by calling Task’s static WaitAll method, or wait any of the tasks to complete synchronously by calling Task’s static WaitAny method.
  5. If you want to create a bunch of tasks with the same creation/continuation settings, you can use TaskFactory’s instance StartNew method.
  6. The task based APM requires a task scheduler to work, the default task scheduler is implemented on top of the thread pool, however, you may change the task scheduler associated with a task to a synchronization context task scheduler, or a customized task scheduler.
  7. You can easily convert a BeginXxx and EndXxx pattern asynchronous operation into a task based APM by calling TaskFactory’s instance FromAsync or FromAsync<T> method.

Task, async method and await expression

I would like to point out that the async method and the await expression/statement in C# 5.0 are implemented in the compiler level by building on top of the task based APM. An async method must have either a return type of void, or a return type of Task or Task<T>, this limitation is obvious because if there is no await expression in the async method, this method will be invoked synchronously; thus this method can be treated as a normal method, making a void return value is clear; otherwise, if the async method contains at least one await expression, this method will be invoked asynchronously and because of await expressions based on the task based APM, a Task or a Task<T> instance must be returned from this method to enable another await expression to perform on this method.

To make this clear, I modify the code to calculate the nth exponent to 2 by using async and await, see the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Task based APM demo");
           
            // Call Exponnent() asynchronously.
            // And immediately return the control flow.
            // If I don't put a Task here, the program will sometimes
            // terminate immediately.
            Task t = new Task(async () =>
            {
                int result = await Program.Exponent(10);

                // After the operation is completed, the control flow will go here.
                Console.WriteLine(result);
            });

            t.Start();
            Console.ReadKey();
        }

        static async Task<int> Exponent(int n)
        {
            Console.WriteLine("Task started");
            return await TaskEx.Run<int>(() => 2 << (n - 1));
        }
    }
}

When I try to run this program, I get the exact same result as the example showed in the Task based APM section.

You may still confuse the above code, concern how it works and what the exactly control flow to run this code. In the coming articles, I will discuss it in details.

Conclusion

The Microsoft .NET Framework provides many ways to perform asynchronous operations, you may choose one or some of them by investigating your case; though there are various ways, some of them are not recommended, such as using System.Threading.Thread class to implement asynchronous operations, or event-based APM. The most popular ways are using thread pool or task based APM. In addition, task based APM is used to implement async method and await expression/statement in C# 5.0.

At last, I summarize the different asynchronous models in the following table for reference.

Pattern Description Based On Notes
Thread based By creating System.Threading.Thread instance Managed Thread Expensive, not recommended
Standard BeginXxx and EndXxx methods By calling BeginXxx method with a user callback; calling EndXxx inside that user callback Thread pool Widely used, standard, recommended, support cancellation and continuation
ThreadPool By calling ThreadPool’s static QueueUserWorkItem method Thread pool Widely used, recommended use as much as possible
Delegate By calling Delegate’s BeginInvoke and EndInvoke instance methods Thread pool Less used
Event based By subscribe appropriate event and calling appropriate method Thread pool Avoid use as much as possible, not recommended
Task based By creating System.Threading.Tasks.Task instance A specified task scheduler Recommended, supports all features of a thread pool pattern, and has many other features
async method and await expression By using async and await keywords Task based pattern The new C# 5.0 asynchronous pattern

Tags: , ,

The features of the C# (Tech Talk)

by Mark Zhou 8. November 2010 19:40

I would like to share one of the Tech Talk content that held in this May, this is a talk about the C# programming language, it is a PPT file and a zip contains the demo source code, it shows the power of C# and the future enhancements with the coming version (C# 5.0).

Here is the PPT file:

This PPT demonstrates the following C# features:

  • dynamic
  • Interoperability
  • Compiler-as-a-Service
  • Metadata programming
  • Attributed programming
  • Outlook add-in
  • Automation tests

This is the source code (must open with Visual Studio 2010 Ultimate, or Test Professional)

Tags: , ,

Translate This Page

About Mark

Mark is a developer who works for building base class libraries and tools for developers.

Mark's Awards

Microsoft Community Contributor

Month List

Who visit this site

Recent Comments

Comment RSS