分類彙整: C#

SOA & Web Services: Basic

Adopt from

[1] http://en.wikipedia.org/wiki/Service-oriented_architecture

[2] http://msdn.microsoft.com/en-us/library/byxd99hx(v=VS.90).aspx

[3] http://msdn.microsoft.com/en-us/library/ms996486.aspx


Developers may prefer object oriented programming nowadays. Instead of installing a piece of assemblies on the local computer, developers want to access the functionalilities hosted in the web directly. Here comes the idea of web service and service-oriented architecture (SOA).

SOA is a flexible set of design principles used during the phases of systems development and integration in computing. A system based on a SOA will package functionality as a suite of interoperable services that can be used within multiple, separate systems from several business domains [1]. In SOA, server will be responsible for the complex computation, and the clients only needs a simple software(e.g. the browser) for the output. In .net framework, we need to do the following in the simplest case:

1. Use the WebMethod attribute in the server side.

public class Service1 : System.Web.Services.WebService
{
    [System.Web.Services.WebMethod(BufferResponse=false)]
    public int Multiple(int a, int b)
    {
       //implementation code
       return (a*b);
    }
}

2. Compile the server code into assembly in WSDL

WSDL describes the complete contract for application communication [3].

3. Client downloads the assembly and imports the assembly into the project.

All networking codes will be generated automatically in the client side system for .Net and Java. This produces the interface using the proxy object, which has a concrete object in the remote server, for the developer to call.

C#: Signatures

Adopt from

[1]C# Language Specification Section 3.6

[2]http://msdn.microsoft.com/en-us/library/586y06yf.aspx

[3]http://msdn.microsoft.com/en-us/library/14akc2c7.aspx

[4]http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx

[5]http://msdn.microsoft.com/en-us/library/ee332485.aspx

[6]http://msdn.microsoft.com/en-us/library/8edha89s.aspx


Methods, instance constructors, indexers, and operators are characterized by their signatures. All signatures must be unique in the class.

Method Signature[1]

consists of the name of the method, the number of type parameters and the number, modifiers, and types of its parameters. The signature of a method does not include the return type. The signature of a method specifically does not include the return type, nor does it include the params modifier that may be specified for the right-most parameter, nor the optional type parameter constraints..

Example[2]

public static void WriteLine( string format, Object arg0 )

WriteLine is the name of the method;

string and Object are the type of each parameters.

Instance Constructor Signature[1]

consists of the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. The signature of an instance constructor specifically does not include the params modifier that may be specified for the right-most parameter.

Example[3]

static void Method(out String s)

String is the type.

out is part of the signature. IS NOT PRECISE

static void Method(out String s) {}

static void Method(ref String s) {}

will produce a compile time error since out and ref are not part of the signature.[6]

Overloading can be done, however, if one method takes a ref or out argument and the other uses neither, like this:

static void Method(out String s) {}

static void Method(String s) {}

Because of this result, I think out and ref both generate the same signature but with different implementation in CIL.

Indexer Signature[1]

consists of the type of each of its formal parameters, considered in the order left to right. The signature of an indexer specifically does not include the element type.

Example[4]

public T this[int i]

The type is int.

Operator Signature[1]

consists of the name of the operator and the type of each of its formal parameters, considered in the order left to right. The signature of an operator specifically does not include the result type.

Example[5]

public static Complex operator +(Complex c1, Complex c2)

Name is Complex

Type is Complex

Use of Signatures[1]

Signatures are the enabling mechanism for overloading of members in classes, structs, and interfaces:

  • Overloading of methods permits a class, struct, or interface to declare multiple methods with the same name, provided their signatures are unique within that class, struct, or interface.
  • Overloading of instance constructors permits a class or struct to declare multiple instance constructors, provided their signatures are unique within that class or struct.
  • Overloading of indexers permits a class, struct, or interface to declare multiple indexers, provided their signatures are unique within that class, struct, or interface.
  • Overloading of operators permits a class or struct to declare multiple operators with the same name, provided their signatures are unique within that class or struct.

Silverlight: Isolated Storage and Serialization

Reference from

[1]http://msdn.microsoft.com/en-us/library/3ak841sy(v=VS.95).aspx

[2]http://msdn.microsoft.com/en-us/library/cc265154(v=VS.95).aspx

[3]http://msdn.microsoft.com/en-us/library/cc221360(v=VS.95).aspx

[4]http://msdn.microsoft.com/en-us/library/x7dzh4ws(v=VS.95).aspx

[5]Programming Windows Phone 7 by Charles Petzold>


What is Isolated Storage in Silverlight?

Isolated storage is a space for the application to store some files. With isolated storage, data is always isolated by the user in a virtual file system that can be just one file in the root directory or a tree of directories and files.[1] It is said to be isolated since every program has access to its own area of permanent disk storage.[5]

When is isolated storage used?

It is when you need to restore the states for every instance of an application, for example, tomestoning.

What namespace should I use?

System.IO.IsolatedStorage namespace[4]

How to use Isolated Storage in Silverlight?

I have copied some codes for save to and load from an Isolated Storage from [5]. Assume the code is in the class Settings.

public void Save()
{
    IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
    IsolatedStorageFileStream stream = storage.CreateFile("settings.xml");
    XmlSerializer xml = new XmlSerializer(GetType()); //Serialize the class
    xml.Serialize(stream, this);
    stream.Close();
    stream.Dispose();
}

public static Settings Load()
{
    IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
    Settings settings;
    if (storage.FileExists("settings.xml"))
    {
        IsolatedStorageFileStream stream =
        storage.OpenFile("settings.xml", FileMode.Open);
        XmlSerializer xml = new XmlSerializer(typeof(Settings));
        settings = xml.Deserialize(stream) as Settings; //Deserialize the class
        stream.Close();
        stream.Dispose();
    }
    else
    {
        settings = new Settings();
    }
        return settings;
    }
}

DotNetFramework: OnNavigateTo and OnNavigateFrom

[1]http://msdn.microsoft.com/en-us/library/cc838245(v=VS.96).aspx

[2]http://msdn.microsoft.com/en-us/library/system.windows.controls.page.onnavigatedto(v=VS.96).aspx

[3]http://msdn.microsoft.com/en-us/library/system.windows.controls.page.onnavigatingfrom(v=VS.96).aspx

[4]Programming Windows Phone 7 by Charles Petzold


What are OnNavigateTo and OnNavigateFrom?

OnNavigateTo is called when a page becomes the active page in a frame.[1]

OnNavigateFrom is called just before a page is no longer the active page in a frame.[1]

How are they related?

For example, MainPage calls Navigate with an argument of "/SecondPage.xaml". The OnNavigatedFrom method in MainPage is called with event arguments with a Uri property indicating "/SecondPage.xaml" and a Content property of type SecondPage. This is the newly created instance of SecondPage that is about to be displayed, and this is the most convenient way to obtain that instance. The OnNavigatedTo method of SecondPage is then called with the same event arguments indicating a Uri of "/SecondPage.xaml" and the SecondPage object.

Similarly, when SecondPage calls GoBack, its OnNavigatedFrom method is called with event arguments that include a Uri property indicating "/MainPage.xaml" and a Content property with the MainPage instance. The OnNavigatedTo method of MainPage is then called with those same event arguments.[4]

MainPage ------OnNavigateFrom---------OnNavigateTo-----------------------> SecondPage

MainPage <------OnNavigateTo---------OnNavigateFrom----------------------- SecondPage

Any public members of the page can be used inside OnNavigateFrom method.

For instance, you have a public property PropertyA

protected override void OnNavigatedFrom(NavigationEventArgs args)

{

    if (args.Content is MainPage)

        (args.Content as MainPage).PropertyA = "ABC"; //asume propertyA can be used to set a string.

    base.OnNavigatedFrom(args);

}

C#: Thread Pools

[1]http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx

[2]Professional C# 2008 by Christian Nagel et al.  Wrox Press c 2008


Scenario

Creating threads takes time. If we create the threads in advance, the resources cannot be released efficiently unless the number of threads can vary.

Solution

We can make a list by ourselves. We can also use the ThreadPool class, which provides a pool of threads that can be used to post work items, process asynchronous I/O, wait on behalf of other threads, and process timers.

Case 1 – Number of Worker Thread = 1, Number of IO Thread = 1

using System;
using System.Threading;

namespace Examples.Threading
{
    class Program
    {
        static void Main()
        {
            ThreadPool.SetMaxThreads(1, 1);
            for (int i = 0; i < 10; i++)
            {
                ThreadPool.QueueUserWorkItem(MainFromThread);
            }

            Thread.Sleep(5000); //Since all thread pool threads are background threads, the main thread ends will abort all the threads inside thread pool.
            Console.WriteLine("Main thread completes its job.");
        }

        static void MainFromThread(object o)
        {
            Console.WriteLine("Task 1 starts by thread {0} in thread pool.", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("Task 2 starts by thread {0} in thread pool.", Thread.CurrentThread.ManagedThreadId);    
        }
    }
}

The thread pool only allows one more new thread so only when a thread in the thread pool is finished, next thread will start. The output should be similar to below but the thread ID, which must appear in even number of times consecutively.

Task 1 starts by thread 4 in thread pool.
Task 2 starts by thread 4 in thread pool.
Task 1 starts by thread 10 in thread pool.
Task 2 starts by thread 10 in thread pool.
Task 1 starts by thread 4 in thread pool.
Task 2 starts by thread 4 in thread pool.
Task 1 starts by thread 4 in thread pool.
Task 2 starts by thread 4 in thread pool.
Task 1 starts by thread 4 in thread pool.
Task 2 starts by thread 4 in thread pool.
Task 1 starts by thread 4 in thread pool.
Task 2 starts by thread 4 in thread pool.
Task 1 starts by thread 4 in thread pool.
Task 2 starts by thread 4 in thread pool.
Task 1 starts by thread 4 in thread pool.
Task 2 starts by thread 4 in thread pool.
Task 1 starts by thread 4 in thread pool.
Task 2 starts by thread 4 in thread pool.
Task 1 starts by thread 11 in thread pool.
Task 2 starts by thread 11 in thread pool.

Case 2 – Number of Worker Thread = 2, Number of IO Thread = 1

using System;
using System.Threading;

namespace Examples.Threading
{
    class Program
    {
        static void Main()
        {
            ThreadPool.SetMaxThreads(2, 1);
            for (int i = 0; i < 10; i++)
            {
                ThreadPool.QueueUserWorkItem(MainFromThread);
            }

            Thread.Sleep(5000); //Since all thread pool threads are background threads, the main thread ends will abort all the threads inside thread pool.
            Console.WriteLine("Main thread completes its job.");
        }

        static void MainFromThread(object o)
        {
            Console.WriteLine("Task 1 starts by thread {0} in thread pool.", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("Task 2 starts by thread {0} in thread pool.", Thread.CurrentThread.ManagedThreadId);    
        }
    }
}

You will see that two tasks of task 1 may start at the consecutively because the number of worker thread is set to 2 now.

Number of IO Thread

The principle of the number of IO thread is same as the number of worker thread while number of IO thread is related to the reading and writing of data.

Limitation and Practice when using ThreadPool[2]

  1. Can only store background threads but also cannot change the background threads inside thread pool to foreground thread.
  2. Cannot set priority or name of a pooled thread.
  3. For COM objects, all pooled threads are multithreaded apartment (MTA) threads. Many COM objects require a single-threaded apartment (STA) thread.
  4. Use pooled threads only for a short task. For threads that are running all the time, it would be better if you create a thread using Thread class. (see C#- Thread Class – ThreadStart and ParameterizedThreadStart)

C#: Foreground Threads and Background Threads

[1]http://msdn.microsoft.com/en-us/library/h339syd0.aspx

[2]Professional C# 2008 by Christian Nagel et al.  Wrox Press c 2008


What is the main different between foreground threads and background threads?

The process of the application keeps running as long as at least one foreground thread is running. If more than one foreground thread is running and the Main() method ends, the process of the application keeps active until all foreground threads finish their work.[2] However, the background threads will end if all foreground threads end. In technical terms, Background threads are identical to foreground threads with one exception: a background thread does not keep the managed execution environment running.[1]

Sample Code – Foreground Thread

using System;
using System.Threading;

namespace Examples.Threading
{
    class Program
    {
        static void Main()
        {
            Thread t1 = new Thread(MainFromThread);
            t1.Name = "ForegroundThread";
            t1.IsBackground = false; //Means foreground thread
            t1.Start();
            Console.WriteLine("Main thread completes its job.");
        }

        static void MainFromThread()
        {
            Console.WriteLine("Thread {0} starts.", Thread.CurrentThread.Name);
            Thread.Sleep(3000);
            Console.WriteLine("Thread {0} ends.", Thread.CurrentThread.Name);
        }
    }
}

//You will always see three lines of ouput.

Sample Code – Background Thread

using System;
using System.Threading;

namespace Examples.Threading
{
    class Program
    {
        static void Main()
        {
            Thread t1 = new Thread(MainFromThread);
            t1.Name = "BackgroundThread";
            t1.IsBackground = true; //Means background thread
            t1.Start();
            Console.WriteLine("Main thread completes its job.");
        }

        static void MainFromThread()
        {
            Console.WriteLine("Thread {0} starts.", Thread.CurrentThread.Name);
            Thread.Sleep(3000);
            Console.WriteLine("Thread {0} ends.", Thread.CurrentThread.Name);
        }
    }
}

//You can at least see the output from Main thread and at most see the start message from the new thread but never the end message from it since all foreground threads(i.e. main thread in this case) are ended within 3 seconds.

C#: Thread Class – ThreadStart and ParameterizedThreadStart

[1]http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx

[2]http://msdn.microsoft.com/en-us/library/system.threading.thread.thread.aspx

[3]Professional C# 2008 by Christian Nagel et al.  Wrox Press c 2008


Simple Examples

In C#, we have a Thread Class. Below is a very simple code to show how do you use a class.

Code – 1st Generation – Simple to Understand

using System;
using System.Threading;

namespace Examples.Threading
{
    class Program
    {
        static void Main()
        {
            Thread t1 = new Thread(MainFromThread);
            Thread t2 = new Thread(MainFromThread);
            t1.Start();
            Console.WriteLine("Every program has a main thread.");
            t2.Start();
        }

        static void MainFromThread()
        {
            Console.WriteLine("When starting a new thread, this line will execute in this thread.");
        }
    }
}

Output

Every program has a main thread.
When starting a new thread, this line will execute in this thread.
When starting a new thread, this line will execute in this thread.

OR

When starting a new thread, this line will execute in this thread.
Every program has a main thread.
When starting a new thread, this line will execute in this thread.

Which one do you think is the correct output?

Actually, both outputs are possible. This is no guarantee as what output comes first. Threads are scheduled by the operating system. Of course, most of the time, the t2 is scheduled in a lower rank due to the invoking sequence.

Code – 2nd Generation – Using Lamda Expression

using System;
using System.Threading;

namespace Examples.Threading
{
    class Program
    {
        static void Main()
        {
            Thread t1 = new Thread(
                () =>
                {
                    Console.WriteLine("When starting a new thread, this line will execute in thread 1.");
                    //Something more to do for this thread
                }
                );
            Thread t2 = new Thread(
                () =>
                {
                    Console.WriteLine("When starting a new thread, this line will execute in thread 2.");
                }
                );
            t1.Start();
            Console.WriteLine("Every program has a main thread.");
            t2.Start();
        }
    }
}

Code – 3rd Generation – No more reference variable (And you will see that thread ID does not relate to the sequence of execution)

using System;
using System.Threading;

namespace Examples.Threading
{
    class Program
    {
        static void Main()
        {
            //Thread 1
            new Thread(
                () =>
                {
                    Console.WriteLine("When starting a new thread, this line will execute in thread with ID {0}.", Thread.CurrentThread.ManagedThreadId);
                    //Something more to do for this thread                   
                }
                ).Start();

            Console.WriteLine("Every program has a main thread with ID {0}.", Thread.CurrentThread.ManagedThreadId);

            //Thread 2
            new Thread(
                () =>
                {
                    Console.WriteLine("When starting a new thread, this line will execute in thread  with ID {0}.", Thread.CurrentThread.ManagedThreadId);
                }
                ).Start();
        }
    }
}

After reading the sample code above, some readers may notice that the thread only accepts delegate parameter, which defines a method with a void return type and without arguments. Actually, it is not a must. The constructor of Thread class accepts a delegate of ThreadStart(see Thread(ThreadStart)), which is used above, and ParameterizedThreadStart(see Thread(ParameterizedThreadStart)) (and two more kinds of contructor). Using ParameterizedThreadStart, you can pass the data to a thread.

ParameterizedThreadStart

ParameterizedThreadStart delegate is defined as follow:

delegate void ParameterizedThreadStart(object o);

Therefore, you need a method that must have a parameter of type object and a void return type.

閱讀全文

C#: Create a Thread - Asychronous Delegates

Reference from

[1] Professional C# 2008 by Christian Nagel et al.  Wrox Press c 2008

[2] http://msdn.microsoft.com/en-us/library/h80ttd5f.aspx


Previously, we have introduced the basic knowledge of thread. In this post, we will start to create some threads. There are two ways to create a thread.

Asychronous Delegates

We first define a delegate and invoking the delegate asynchronously. The Delegate class also supports invoking the mehods asynchronously. Behind the scenes, the Delegate class creates a thread that fulfills the task.

Preparation

We need to create a method so that a delegate will call this method later.

static string TakesAWhile(int timeout)

{

    Console.WriteLine("TakesAWhile started, listening for a response");

    Thread.Sleep(timeout); //in millisecond

    Console.WriteLine("TalesAWhile ended");

    return "Data received";

}

To invoke this method from a delegate, we need to create a delegate

public delegate string TakesAWhileDelegate(int timeout);

To invoke the delegate asychronously and have the result returned, we can use different techniques.

Method I – Polling

Poll and check if the delegate has already finished its work using IAsyncResult. When the result is returned, which also means that the method is completed, IAsyncResult.IsCompleted is true.

static void Main()

{

    // synchronous method call

    // TakesAWhile(1000);

    // asynchronous by using a delegate

    TakesAWhileDelegate tawDelegate = TakesAWhile;

    IAsyncResult ar = tawDelegate.BeginInvoke(2000, null, null); //Timeout is 2 seconds

    while (!ar.IsCompleted) //That means the result is not returned yet.

    {

        // doing something else in the main thread

        Console.Write(".");

        Thread.Sleep(50);

    }

    string result =  tawDelegate.EndInvoke(ar)

    Console.WriteLine("result: {0}", result);

}

Method II – Wait Handle

We will use WaitOne(), which is an instance method where you can wait for a signal to occur. The signal is generated because the method has finished its work.

static void Main()

{

    // asynchronous by using a delegate

    TakesAWhileDelegate tawDelegate = TakesAWhile;

    IAsyncResult ar = tawDelegate.BeginInvoke(2000, null, null); //Timeout is 2 seconds

    while (true)

    {

        Console.Write(".");

        if (ar.AsyncWaitHandle.WaitOne(80, false)) //each time wait for 80ms to see if the thread is finished

        {

             Console.WriteLine("Can get the result now");

             break;

        }

   }

   string result =  tawDelegate.EndInvoke(ar)

   Console.WriteLine("result: {0}", result);

}

Method III – Asynchronous Callback

When the method finishes, it will call the method supplied in BeginInvoke, which is, in this example, TakesAWhileCompleted.

static void Main()

{

    TakesAWhileDelegate tawDelegate = TakesAWhile;

    tawDelegate.BeginInvoke(2000, TakesAWhileCompleted, tawDelegate);

    for (int i = 0; i < 100; i++)

    {

        Console.Write(".");

        Thread.Sleep(50);

    }

    // not neccearily TakesAWhile is completed

}

static void TakesAWhileCompleted(IAsyncResult ar)

{

    // invoke from the thread of the delegate andnot from the main thread.

    if (ar == null) throw new ArgumentNullException("ar");

    TakesAWhileDelegate tawDelegate = ar.AsyncState as TakesAWhileDelegate;

    Trace.Asset(ar != null, "Invalid object type");

    string result =  tawDelegate.EndInvoke(ar);

    Console.WriteLine("result: {0}", result);

}

C#: Bitmap Manipulation

Adopt from

[1]http://ilab.ahemm.org/tutBitmap.html#codesamples

Reference from

[2]http://stackoverflow.com/questions/319993/c-hexadecimal-notation-and-signed-integers

[3]http://msdn.microsoft.com/en-us/library/aa473780(VS.85).aspx

[4]http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx

[5]Marshal.Copy Method (System.Runtime.InteropServices)


Introduction

C# can make per pixel change to a bitmap. Before go into the code, there are some basic concepts related to an image.

Data Storage of an Image

Do you know how to calculate the image size of a bitmap? You should know this because you need to prepare a data storage in the code, probably using array.

The general formula for the size of the array needed is as follows[1]:

ArrayLength = ImageStride * ImageHeight / ArrayTypeSize

where

The stride is the number of bytes from one row of pixels in memory to the next row of pixels in memory (involved color depth too).[3] The stride of an image, usually measured in bytes, is the amount of memory a horizontal row of pixels takes up.[1] Stride is also called pitch. If padding bytes are present, the stride is wider than the width of the image, as shown in the following illustration.[3]

Diagram showing image and padding, with callouts for pScanLine0, image width, and stride

Diagram showing image and padding, with callouts for pScanLine0, image width, and stride[3]

We can see that image width is not necessarily same as image stride. This isn't necessarily the width of the image multiplied by the bit-depth too.[1]

Programming in C#

Data Storage

If you have an image in 32bit, it is an A(lpha Level)R(ed)G(reen)B(lue) image. This image usually has a stride of 32bit. We can use an array of 32 bit of integer to stored it. Suppose the array is in one dimension, using

ArrayLength = ImageStride * ImageHeight / ArrayTypeSize

Hence, the array size is

ArrayLength = ImageWidth * ImageHeight

You need to use a System.Runtime.InteropServices.Marshal.Copy (See [5]) to copy the pixel to the array.

Image Locking

Lock the image when you do not want to make changes on some pixels of the image. You may find more information related to Bitmap.LockBits in [4]

Image Manipulation

The pixel is stored in the array. You can use any method, e.g. bitwise operator, to make change on the image. After changes have been made, you may use Marshal.Copy again to output the image, which is stored temporarily in memory. This new image can be shown using a PictureBox or exported it to a Bitmap image.

C# Sample Code

Part of them is adopted from [1] and the blur-function aims at giving more information to the reader.

https://sites.google.com/site/wongpakmemofiles/wongpak-memo-files/MyFirstImageProcessingApplication.7z?attredirects=0&d=1

C#: Thread Basic

Reference

[1]http://msdn.microsoft.com/en-us/library/798axes2.aspx

[2]http://www.c-sharpcorner.com/UploadFile/mgold/MultithreadingIntro10062005000439AM/MultithreadingIntro.aspx?ArticleID=920ecafc-e83b-4a9c-a64d-0b39ad885705

[3]http://msdn.microsoft.com/en-us/library/aa720724.aspx

[4]Thread (computer science) - Wikipedia, the free encyclopedia

[5]http://www.tns.lcs.mit.edu/manuals/java-tutorial/java/threads/definition.html


Introduction

Application runs on operating system. Operating systems use processes to separate the different applications that they are executing.

What is a thread?

Threads are the basic unit to which an operating system allocates processor time. It is a single sequential flow of control with a program.[5] In other word, a thread cannot be separated into more processing. More than one thread can be executing code inside a process.

Each thread maintains exception handlers, a scheduling priority, and a set of structures the system uses to save the thread context until it is scheduled. The thread context includes all the information the thread needs to seamlessly resume execution, including the thread's set of CPU registers and stack, in the address space of the thread's host process.

How does the computer process different threads “simultaneously” in a single process?

On a single processor, multithreading generally occurs by time-division multiplexing (as in multitasking): the processor switches between different threads. This context switching generally happens frequently enough that the user perceives the threads or tasks as running at the same time. On a multiprocessor or multi-core system, the threads or tasks will actually run at the same time, with each processor or core running a particular thread or task.

Many modern operating systems directly support both time-sliced and multiprocessor threading with a process scheduler. The kernel of an operating system allows programmers to manipulate threads via the system call interface. Some implementations are called a kernel thread, whereas a lightweight process (LWP) is a specific type of kernel thread that shares the same state and information.[4]

Using Thread in C#

We will use System.Threading Namespace in .Net. This namespace provides classes and interfaces that enable multithreaded programming.

There are some classes for synchronizing thread activities and access to data, for example, more than one thread make change to the same variable. This namespace also includes a ThreadPool class that allows you to use a pool of system-supplied threads and a Timer class that executes callback methods on thread pool threads.[1]