程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#3.0學習筆記(12)進程,線程和異步編程

C#3.0學習筆記(12)進程,線程和異步編程

編輯:C#入門知識

 

離職在家,沒有什麼事做,所以借這個機會總結一下關於異步編程的技術來跟各位園友分享。

1,什麼叫進程?什麼叫線程?

  進程:進程就是一組資源,它們構成了一個正在運行的程序。這些資源包括虛擬地址空間,文件句柄以及程序啟動需要的其他東西的載體。當我們啟動一個程序時,系統在內存中  

  就創建了一個新的進程(Process)。

  線程:在進程中,系統創建了一個叫做線程(thread)的內核對象,線程體現了一個程序的真實執行情況。一旦程序准備完畢,系統在線程中開始執行Main方法的第一條語句。默

  認情況下,一個進程只包含一個線程,它從程序開始執行一直到程序結束。

2,什麼叫異步編程(或稱為多線程)?

  在理解什麼叫異步編程之前,我們先來看看什麼叫同步編程,到目前為止,我們前面講的所有程序都只有一個線程,並且從程序的第一行語句到最後一行語句順序執行,這就叫同             

  步編程。異步編程指的是程序發起多個線程,它們在理論上是在同一時間執行的。(其實不一定真的在同一時間執行)  

下面來介紹兩種簡單但非常強大的多線程技術,異步委托和計時器:

異步委托:

使用異步委托有三種標准模式:

1,等待一直到完成(wait-until-done)模式:在發起了異步方法以及做了一些其它處理後,原始線程就中斷並且等異步方法完成之後再繼續。

2,輪詢(Polling)模式:原始線程定期檢查發起的線程是否完成,如果沒有則可以繼續做一些其它的事情。

3,回調(Callback)模式:原始線程一直執行,無需等待或檢查發起的線程是否完成。在發起的線程中的引用方法完成之後,發起的線程就會調用回調方法,由回調方法在調用EndInvoke之前處理異步方法的

  結構。

下面是這三種模式的執行過程圖示:

\

 下面就看看這三種模式分別的完整示例:

1,等待一直到結束模式的示例:

 

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

 

namespace thread1

{

    delegate long MyDel(int first,int second); //聲明委托類型

    class Program

    {

        static long Sum(int x, int y) //聲明異步方法,方法匹配委托。

        {

            Console.WriteLine("           Inside Sum");

            Thread.Sleep(100); //調用Thread類的Sleep方法將它自己掛起0.1秒。

            return x + y;

        }

 

        static void Main(string[] args)

        {

            MyDel del = new MyDel(Sum); //創建委托對象,並使用Sum方法來初始化它的調用列表

 

            Console.WriteLine("Before BeginInvoke");

            IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //開始異步調用,BeginInvoke返回一個IAsyncResult接口的引用。

            Console.WriteLine("After BeginInvoke");

 

            Console.WriteLine("Doing stuff");

 

            long result = del.EndInvoke(iar); //等待結束並獲取結果。必須把IAsyncResult對象的引用作為參數。

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

            Console.ReadKey();

        }

    }

}程序輸出結果為:

 

\

 

2,輪詢(Polling)模式的示例:

 

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

 

namespace thread2

{

    delegate long MyDel(int first,int second); //聲明委托類型。

    class Program

    {

        static void Main(string[] args)

        {

            MyDel del = new MyDel(Sum); //創建委托對象。

 

            IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //發起異步調用,BeginInvoke返回一個IAsyncResult接口的引用。

            Console.WriteLine("After BeginInvoke");

 

            while (!iar.IsCompleted) //調用IAsyncResult接口的IsCompleted屬性檢查異步方法是否完成。

            {

                Console.WriteLine("Not Done");

 

                //繼續處理。這裡的“處理”僅僅是由0數到10000000。

                for (long i = 0; i < 10000000; i++)

                    ; //空語句。

            }

            Console.WriteLine("Done");

 

            long result = del.EndInvoke(iar); //調用委托的EndInvoke方法來獲取接口並進行清理。

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

            Console.ReadKey();

 

        }

 

        static long Sum(int x, int y) //聲明方法匹配委托。

        {

            Console.WriteLine("         Inside Sum");

            Thread.Sleep(500); //調用Thread類的Sleep方法將它自己掛起0.5秒。

            return x + y;

        }

    }

}程序輸出結果為:

 

\

 

3,回調(Callback)模式的示例代碼:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

using System.Runtime.Remoting.Messaging;

 

namespace thread3

{

    delegate long MyDel(int first,int second); //聲明委托類型。

 

    class Program

    {

        static long Sum(int x, int y) //聲明方法匹配委托。

        {

            Console.WriteLine("         Inside Sum");

            Thread.Sleep(100); //調用Thread類的Sleep方法將它自己掛起0.1秒。

            return x + y;

        }

 

        static void CallWhenDone(IAsyncResult iar) //聲明回調方法。

        {

            Console.WriteLine("         Inside CallWhenDone");

            AsyncResult ar = (AsyncResult)iar; //通過引用轉換,將接口引用轉換為AsyncResult類對象的引用。

            MyDel del = (MyDel)ar.AsyncDelegate; //調用類對象的AsyncDelegate屬性並把它轉化為委托類型,這樣我們就可以調用委托的EndInvoke方法了。

            long result = del.EndInvoke(iar); //結束調用,獲取異步方法調用的返回值,釋放線程所用資源。

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

        }

 

        static void Main(string[] args)

        {

            MyDel del = new MyDel(Sum); //創建委托對象。

 

            Console.WriteLine("Before BeginInvoke");

            IAsyncResult iar = del.BeginInvoke(3,5,CallWhenDone,null);

 

            Console.WriteLine("Doing more work in Main");

            Thread.Sleep(500);

            Console.WriteLine("Done with Main,Exiting");

            Console.ReadKey();

        }

    }

}

	

程序輸出結果為:

 

\

 

計時器:

計時器提供了另外一種正規的重復運行異步方法的方法。盡管在.NET BCL中有好幾個可用的Timer類,但在這裡我只會介紹System.Threading命名空間中的一個。

使用計時器需要注意的重要事項如下:

1,計時器在每次時間到期後調用回調方法。回調方法必須是TimerCallback委托形式的。

2,當計時器到期之後,系統會從線程池中的線程上開啟一下回調方法,提供state對象作為其參數,並且開始運行。

3,Timer類的構造函數接受回調方法名稱,dueTime,period以及state作為參數,其最為常用的構造函數形式如下:

  Timer myTimer=new Timer(MyCallback,someObject,2000,1000);

  注:MyCallback為回調方法的名稱。

    someObject為傳給回調的對象。

    2000即dueTime表示2000毫秒後第一次調用。

    1000即period表示每1000毫秒調用一次。

示例如下:

 

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

 

namespace thread4

{

    class Program

    {

        int TimesCalled = 0;

 

        protected void Display(object state)//聲明回調方法。

        {

            Console.WriteLine("{0}{1}",(string)state,++TimesCalled);

        }

 

        static void Main(string[] args)

        {

            Program p = new Program();//創建類的實例。

 

            Timer myTimer = new Timer(p.Display,"Processing timer event",2000,1000);//創建Timer類對象。

            Console.WriteLine("Timer start");

            Console.ReadKey();

        }

    }

}這段代碼在被關閉前的5秒內產生了如下的輸出:

 

\

 

  以上就是這次總結的關於多線程編程方面的知識,寫了一下午了。正好今天是我的27歲的生日,我得去准備請同事吃飯了,在這裡也希望自己在新的一年裡身體健康,工作順利。

 

 

 


作者 永遠的麥子

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved