Sunday, October 25, 2009

.Net FrameWork Basics and Basics of MultiThreading

Net Framework basics
When we speak about .Net, we mean by .NET framework. .NET Framework is made up of the Common Language Runtime (CLR), the Base Class Library (System Classes). This allows us to build our own services (Web Services or Windows Services) and Web Applications (Web forms Or Asp .Net), and Windows applications (Windows forms). We can see how this is all put together.?

Above Picture shows overall picture, demonstrating how the .NET languages follows rules provided by the Common Language Specifications (CLS). These languages can all be used?Independently to build application and can all be used with built-in data describers (XML) and data assessors (ADO .NET and SQL). Every component of the .NET Framework can take advantage of the large pre- built library of classes called the Framework Class Library (FCL). Once everything is put together, the code that is created is executed in the Common Language Runtime. Common Language Runtime is designed to allow any .NET-compliant language to execute its code. At the time of writing, these languages included VB .Net, C# and C++ .NET, but any language can become .NET- compliant, if they follow CLS rules. The following sections will address each of the parts of the architecture.


.Net Common Language Specifications (CLS):

In an object-oriented environment, everything is considered as an object. (This point is explained in this article and the more advanced features are explained in other articles.) You create a template for an object (this is called the class file), and this class file is used to create multiple objects.

TIP: Consider a Rectangle. You may want to create many Rectangle in your lifetime; but each Rectangle will have certain characteristics and certain functions. For example, each rectangle will have a specific width and color. So now, suppose your friend also wants to create a Rectangle. Why reinvent the Rectangle? You can create a common template and share it with others. They create the Rectangle based on your template. This is the heart of object-oriented programming?the template is the class file, and the Rectangle is the objects built from that class. Once you have created an object, your object needs to communicate with many other Objects.

Even if it is created in another .NET language doesn?t matter, because each language follows the rules of the CLS. The CLS defines the necessary things as common variable types (this is called the Common Type System CTS ), common visibility like when and where can one see these variables, common method specifications, and so on. It doesn?t have one rule which tells how C# composes its objects and another rule tells how VB .Net does the same thing . To steal a phrase, there is now ?One rule to bind them all.? One thing to note here is that the CLS simply provides the bare rules. Languages can adhere to their own specification. In this case, the actual compilers do not need to be as powerful as those that support the full CLS.

The Common Language Runtime (CLR):

The heart of .net Framework is Common Language Runtime (CLR). All .NET-compliant languages run in a common, managed runtime execution environment. With the CLR, you can rely on code that is accessed from different languages. This is a huge benefit. One coder can write one module in C#, and another can access and use it from VB .Net. Automatic object management, the .NET languages take care of memory issues automatically. These are the few listed?benefits which you get from CLR.

Microsoft Intermediate Language (MSIL):

So how can many different languages be brought together and executed together??Microsoft Intermediate Language (MSIL) or, as it?s more commonly known, Intermediate Language (IL). In its simplest terms, IL is a programming language.?If you wanted to, you could write IL directly, compile it, and run it. But why would want to write such low level code? Microsoft has provided with higher-level languages, such as C#, that one can use. Before the code is executed, the MSIL must be converted into platform

-specific code. The CLR includes something called a JIT compiler in which the compiler order is as follows.

Source Code => Compiler => Assembley =>Class Loader =>Jit Compiler =>Manged Native Code=>Execution.

The above is the order of compilation and execution of programs. Once a program is written in a .Net compliant language, the rest all is the responsibility of the frame work.

Note:-- MSIL is become CIL(Common Intermediate language) in .net framework and above.

The Basics of .NET Framework Interoperability

Platform Interoperability
This article gives an overview of the platform invoke service in order to show how managed code calls a native function contained in a DLL. Assume your application might need to take control of Microsoft Office Excel and perform a processing routine. Because the Excel library is not written in .NET, you would need to access it through the Component Object Model (COM). COM is a set of specifications meant to form a programming discipline for writing resuable software components that can be inserted into an operating system as a binary entity. The topic of COM and .NET interop is out of the scope of this paper. But the only way to share libraries is through interop. The platform service is an internal call mechansim that enables interoperation because the System.Runtime.InteropSevices namespace contains classes where some of which define the methods that enable a C# program to call raw C DLL.
The Platform Invoke Service Platform Invoke is a service that enables managed code to call an unmanaged function contained in raw C DLLs, functions that are implemented in dynamically-linked libraries, such as those found in the win32 API. It locates and invokes an exported function and marshals its arguments (integers, strings, arrays, structures, and so on) across the interoperation boundary as needed. The CLR used together with certain base classes of defined in the System.Runtime.InteropServices namespace the .NET Framework allows managed code to directly call functions in native code. These base classes are defined in the System.Runtime.InteropServices namespace.
To call a function from a DLL export from a C# program you must declare this function within a C#:

• Declare the method by using the static and extern keywords.

• Attach the DLL import attribute to the method

• The DLLImport attribute allows you to specify the name of the method contained in the DLL.

This example shows you how to use the DllImport attribute to create a message box by calling MessageBoxA from user32.dll. To examine the functions contained insystem component, use the dumpbin.exe tool that ships with the Microsoft Windows SDK:dumbin.exe user32.dll /all > user.txt
Example

/***** File: example.cs *****/

using System;

using System.Runtime.InteropServices;

// import the namespaceclass PlatformInvokeTest

// declare the class {[DllImport("user32.dll")]

//the Dllmport attribute public static extern int MessageBoxA(

// methods int h, string m, string c, int type);public static int Main()

// entry point {return MessageBoxA(0, "This is a Windows object!", "My MessageBox", 0);

// end of method}

// end of class}



/****************************************************************/

To compile:


c:\%windir%\Microsoft.NET\Framework\v2.0.50727>csc.exe example.cs
A Closer Look at Platform Invoke
There are two ways that C# code can directly call unmanaged code:

• Directly call a function exported from a DLL.

• Call an interface method on a COM object.

For both techniques, you must provide the C# compiler with a declaration of the unmanaged function, and you may also need to provide the C# compiler with a description of how to marshal the parameters andreturn value to and from the unmanaged code.
This section tutorial consists of the following topics:

• Calling a DLL Export Directly from C#.

• Default Marshaling and Specifying Custom Marshaling for Parameters to Unmanaged Methods

The sction includes the following examples:

• Example 1 Using DllImport

• Example 2 Overriding Default Marshaling

To declare a method as having an implementation from a DLL export, do the following:

• Declare the method with the static and extern C# keywords.

• Attach the DllImport attribute to the method. The DllImport attribute allows you to specify the name of the DLL that contains the method. The common practice is to name the C# method the same as the exported method, but you can also use a different name for the C# method. DLLs contain export tables of semantically related functions.

• Optionally, specify custom marshaling information for the method's parameters and return value, which will override the .NET Framework default marshaling.

Example 1
This example shows you how to use the DllImport attribute to output a message by calling puts frommsvcrt.dll.

// PInvokeTest.cs

using System;

using System.Runtime.InteropServices;

class PlatformInvokeTest

{

[DllImport("msvcrt.dll")]

public static extern int puts(string c);

[DllImport("msvcrt.dll")]

internal static extern int _flushall(); public static void Main() { puts("Test"); _flushall(); }

}

OutputTest
How it works:
The preceding example shows the minimum requirements for declaring a C# method that is implemented in an unmanaged DLL. The method PlatformInvokeTest.puts is declared with the static and extern modifiers and has the DllImport attribute which tells the compiler that the implementation comes from msvcrt.dll, using the default name of puts. To use a different name for the C# method such as putstring, you must use the EntryPoint option in the DllImport attribute, that is: [DllImport("msvcrt.dll", EntryPoint="puts")].
Default Marshaling and Specifying Custom Marshaling for Parameters toUnmanaged Methods When calling an unmanaged function from C# code, the common language runtime must marshal the parameters and return values. For every .NET Framework type there is a default unmanaged type, which the common language runtime will use to marshal data across a managed to unmanaged function call. For example, the default marshaling for C# string values is to the type LPTSTR (pointer to TCHAR char buffer). You can override the default marshaling using the MarshalAs attribute in the C# declaration of the unmanaged function.

Example 2
This example uses the DllImport attribute to output a string. It also shows you how to override the default marshaling of the function parameters by using the MarshalAs attribute.

// Marshal.cs

using System;

using System.Runtime.InteropServices;

class PlatformInvokeTest

{

[DllImport("msvcrt.dll")]

public static extern int puts([MarshalAs(UnmanagedType.LPStr)] string m);

[DllImport("msvcrt.dll")]

internal static extern int _flushall();

public static void Main()

{

puts("Hello World!"); _flushall();

}

}


Output
When you run this example, the string,

Hello World!
will display on console output.

To illustrate the .NET assembly a unit of deployment:
C:\Widows\Microsoft.NET\Framework\v2.0.50727>ildasm.exe /metadata=validate /out:Marshal.il Marshal.exe

C:\Widows\MicrosoftNET\Framework\v2.05072>ilasm.exe Marshal.il
Microsoft (R) .NET Framework IL Assembler. Version 2.0.50727.1433

Copyright (c) Microsoft Corporation. All rights reserved.

Assembling 'Marshal.il' to EXE --> 'Marshal.exe'

Source file is ANSIAssembled method PlatformInvokeTest::Main

Assembled method PlatformInvokeTest::.ctor

Creating PE file

Emitting classes:

Class 1: PlatformInvokeTestEmitting fields and methods:

Global

Class 1 Methods: 4;

Resolving local member refs: 2 -> 2 defs, 0 refs, 0 unresolved

Emitting events and properties:

Global

Class 1

Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved

Writing PE file

Operation completed successfully
C:\Windows\Microsoft.NET\Framework\v2.0.50727>ngen Marshal.exe

Microsoft (R) CLR Native Image Generator - Version 2.0.50727.1433

Installing assembly C:\Windows\Microsoft.NET\Framework\v2.0.50727\Marshal.exe

Compiling assembly C:\Windows\Microsoft.NET\Framework\v2.0.50727\Marshal.exe

...

marshal, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

C:\Windows\Microsoft.NET\Framework\v2.0.50727>sn -k Marshal.key

Microsoft (R) .NET Framework Strong Name Utility Version 2.0.50727.42

Key pair written to Marshal.key
C:\Windows\Microsoft.NET\Framework\v2.0.50727>sn -p Marshal.key Marshal.PublicKey

Microsoft (R) .NET Framework Strong Name Utility Version 2.0.50727.42

Public key written to Marshal.PublicKey
C:\Windows\Microsoft.NET\Framework\v2.0.50727>sn -tp Marshal.PublicKey

Microsoft (R) .NET Framework Strong Name Utility Version 2.0.50727.42

Public key is

0024000004800000940000000602000000240000525341310004000001000100d7eff35e758fb7

6027164c638288029538cc3c15588efb97c090dc6b45ecbf2dd3afd9ad5a13e26aa3698b9cdf87

905039c73174a4cd99a93f98e4e49a5dc4eaa62423f542056b058dd8ae69ac54b324ba76b5be29

487e8b3ad49f2be7896aa56478bfda857526ea69823dbceb019bd378a4ee607f060b7583fa9a3a

fdcfe3ae

Public key token is bbd777f8c6ef0f35

C:\Windows\Microsoft.NET\Framework\v2.0.50727>csc.exe /keyfile:Marshal.key Marshal.cs C:\Windows\Microsoft.NET\Framework\v2.0.50727>gacutil -i Marshal.exe

Microsoft (R) .NET Global Assembly Cache Utility. Version 2.0.50727.42

Assembly successfully added to the cache

C:\Windows\Microsoft.NET\Framework\v2.0.50727>csc /doc:Marshal.xml Marshal.cs

C:\Windows\Microsoft.NET\Framework\v2.0.50727>notepad Marshal.xml

marsha

 
C:\Windows\Microsoft.NET\Framework\v2.0.50727>xsd.exe /c Marshal.xml

Microsoft (R) Xml Schemas/DataTypes support utility

[Microsoft (R) .NET Framework, Version 2.0.50727.42]

Writing file 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\Marshal.xsd'.

PInvoke provides a way for managd coe to all unmanaged functions implmented in aC DLL. The .NET devloper can avoid locating and invoking the corect function export. Current tehnical documentation states that many companies keep large code bases of legacy code. The need to become proficient with interop is evident.

Basics of .NET Framework multithreaded programming

Writing multithreaded .NET applications can be tough for beginning programmers. I'll show you how to create threads and how the syntax differs for VB.NET and C#.

Multithreaded programming can be a little daunting for novice programmers, but the .NET Framework has considerably simplified the process. In fact, almost any programmer can delve into it and master the fundamentals. I'll introduce you to the basics of multithreaded programming and provide some sample code you can use to start experimenting.

Creating threads

To get multithreaded programming running, you must first create an instance of a Thread. You don’t have much in the way of options, as there is only one constructor:

C#

public Thread( ThreadStart start );

The parameter ThreadStart is a delegate to the method that is the starting point of the thread. The signature of the delegate is a method with no parameters and returns nothing, as demonstrated below:

C#

public delegate void ThreadStart();

Starting threads

One thing that may not be obvious when you first start working with threads is that creating an instance of the Thread object does not cause the thread to start. To get the thread to start, you need to call the Thread class’s Start() method, like this:

C#

public void Start();

Getting a thread to sleep

When developing a thread, you may find that you don’t need it to continually run, or you might want to delay the thread while some other thread runs. To handle this, you could place a delay loop like a “do-nothing” for-loop. But that would waste CPU cycles. Instead, you should temporarily stop the thread or put it to sleep.

Doing this couldn’t be easier. Simply add the following static/shared Sleep() method:

C#

public static void Sleep(int);

This line causes the current thread to go to sleep for the interval specified either in an integer value of milliseconds, as the examples above show, or using a TimeSpan structure.
The Sleep() method also takes two special values: Infinite, which means sleep forever, and 0, meaning give up the rest of the thread’s current CPU time slice.

A neat thing to remember is that the main function is also a thread. This means you can use Sleep() to make any application sleep.

Aborting threads

You might, on occasion, require that a thread be terminated within another thread before it runs through to its normal end. In such a case, you would call the Abort() method. Normally, this method will permanently stop the execution of a specified thread:

C#

public void Abort();

Notice, I said normally. When a thread is requested to stop with the Abort() method, a ThreadAbortException is actually thrown within the thread. This exception, like any other, can be caught. But unlike most other exceptions, the ThreadAbortException is special: It gets rethrown at the end of the catch block unless the aborting thread’s ResetAbort() method is called. Calling the ResetAbort() method cancels the abort, which, in turn, prevents the ThreadAbortException from stopping the thread.

C#

public static void ResetAbort();

Be aware that an aborted thread can't be restarted. If you attempt to do so, a ThreadStateException exception is thrown instead.

Joining threads

What if you want to execute something immediately after the threads finish? Or more generally, how do you handle the scenario where one thread needs to wait for another thread to complete before continuing? You need to join the threads using the Join() method:

C#

public void Join();
You can join threads by using one of the three overloaded Join() methods. The first overloaded method, as shown above, takes no parameters and waits until the thread completes. The second takes an Integer/int/Int32 parameter and then waits the parameter’s specified number of milliseconds or for the thread to terminate, whichever is shorter. The third overload takes a TimeSpan and functions the same as the previous overload.

Interrupting threads

It's possible to take a worker thread that is waiting for something to happen and place it in a tight loop, waiting for that event to occur. But again, this would be a big waste of CPU cycles. It's better to let the worker thread sleep and then be woken up when the event occurs. We can do that using a combination of Sleep() and Interrupt() methods in conjunction with ThreadInterruptedException:

C#

public void Interrupt();

The basic idea is to put the worker thread to sleep using the Sleep() method and then to use the Interrupt() member method to interrupt the sleep of the worker thread when the required event occurs. Simple enough, except that the Interrupt() method throws a ThreadInterruptedException instead of just terminating the Sleep() method. Thus, you need to use exception handling and place the Sleep() method in a try block. Then, have the worker thread continue execution in the catch block.

For instance, in the worker thread, you'd have the following (pseudo) code:

Try

<< Wait for event to occur >>

catch << A ThreadInterruptedException >>

<>

You'd then have some other thread execute the Interrupt() method to get the above thread to continue.

Suspending and resuming threads

Interrupting will work fine if the worker thread knows when to go to sleep. You may also need to allow another thread to temporarily stop a different thread and then restart it again later.
For example, a worker thread could be doing some intense number crunching when along comes another thread that needs to put a large graphic up on the monitor ASAP. (User interface should almost always get priority.)

This scenario can be resolved in at least three ways. You could do nothing special and let the multithreading engine slowly display the graphic. You could raise the priority of the graphic display thread (or lower the priority of the worker thread), thus giving the graphic display more cycles. Or you could suspend the worker thread using the Suspend() method:

C#

public void Suspend();

Then, you could draw the graphic and resume the worker thread using the Resume() method:

C#

public void Resume();
Background and foreground threads

Two types of threads are available. The first is the foreground thread, which runs until it reaches its exit point or is aborted. The second is the background thread, which terminates upon the completion of the last foreground thread. When you create a thread using the Thread class’ constructor, you create a foreground thread by default. To change the thread to a background thread, you must change its IsBackground property to true. The IsBackground property can be toggled at any time while the thread is running.

As you start to play with threads, you'll come to realise that even though they're easy to code, they're not easy to work with. You will spend a lot of time just trying to get your threads to synchronise. Hence, the inordinate number of Sleep() and Join() method calls placed in the simple example.

Remember, these are just the basics.

No comments: