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

來源:互聯網
上載者:User

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

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歲的生日,我得去準備請同事吃飯了,在這裡也希望自己在新的一年裡身體健康,工作順利。


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.