无码视频在线观看,99人妻,国产午夜视频,久久久久国产一级毛片高清版新婚

  • 始創(chuàng)于2000年 股票代碼:831685
    咨詢熱線:0371-60135900 注冊有禮 登錄
    • 掛牌上市企業(yè)
    • 60秒人工響應
    • 99.99%連通率
    • 7*24h人工
    • 故障100倍補償
    全部產(chǎn)品
    您的位置: 網(wǎng)站首頁 > 幫助中心>文章內(nèi)容

    細說多線程(五) —— CLR線程池的I/O線程

    發(fā)布時間:  2012/9/16 6:35:56

    目錄

    一、線程的定義

    二、線程的基礎知識

    三、以ThreadStart方式實現(xiàn)多線程

    四、CLR線程池的工作者線程

    五、CLR線程池的I/O線程

    六、異步 SqlCommand

    七、并行編程與PLINQ

    八、計時器與鎖

     

    五、CLR線程池的I/O線程

    在前一節(jié)所介紹的線程都屬于CLR線程池的工作者線程,這一節(jié)開始為大家介紹一下CLR線程池的I/O線程

    I/O 線程是.NET專為訪問外部資源所設置的一種線程,因為訪問外部資源常常要受到外界因素的影響,為了防止讓主線程受影響而長期處于阻塞狀態(tài),.NET為多 個I/O操作都建立起了異步方法,例如:FileStream、TCP/IP、WebRequest、WebService等等,而且每個異步方法的使用 方式都非常類似,都是以BeginXXX為開始,以EndXXX結束,下面為大家一一解說。

     

    5.1  異步讀寫 FileStream

    需要在 FileStream 異步調(diào)用 I/O線程,必須使用以下構造函數(shù)建立 FileStream 對象,并把useAsync設置為 true。

    FileStream stream = new FileStream ( string path, FileMode mode, FileAccess access, FileShare share, int bufferSize,bool useAsync ) ;

    其中 path 是文件的相對路徑或絕對路徑; mode 確定如何打開或創(chuàng)建文件; access 確定訪問文件的方式; share 確定文件如何進程共享; bufferSize 是代表緩沖區(qū)大小,一般默認最小值為8,在啟動異步讀取或?qū)懭霑r,文件大小一般大于緩沖大小; userAsync代表是否啟動異步I/O線程。

    注意:當使用 BeginRead 和 BeginWrite 方法在執(zhí)行大量讀或?qū)憰r效果更好,但對于少量的讀/寫,這些方法速度可能比同步讀取還要慢,因為進行線程間的切換需要大量時間。

     

    5.1.1 異步寫入

    FileStream中包含BeginWrite、EndWrite 方法可以啟動I/O線程進行異步寫入。

    public override IAsyncResult BeginWrite ( byte[] array, int offset, int numBytes, AsyncCallback userCallback, Object stateObject )
    public override void EndWrite (IAsyncResult asyncResult )

     

    BeginWrite 返回值為IAsyncResult, 使用方式與委托的BeginInvoke方法相似,最好就是使用回調(diào)函數(shù),避免線程阻塞。在最后兩個參數(shù)中,參數(shù)AsyncCallback用于綁定回調(diào) 函數(shù); 參數(shù)Object用于傳遞外部數(shù)據(jù)。要注意一點:AsyncCallback所綁定的回調(diào)函數(shù)必須是帶單個 IAsyncResult 參數(shù)的無返回值方法。
    在例子中,把FileStream作為外部數(shù)據(jù)傳遞到回調(diào)函數(shù)當中,然后在回調(diào)函數(shù)中利用IAsyncResult.AsyncState獲取FileStream對象,最后通過FileStream.EndWrite(IAsyncResult)結束寫入。

         class Program
         {
             static void Main(string[] args)
             {
                 //把線程池的最大值設置為1000
    ThreadPool.SetMaxThreads(1000, 1000); ThreadPoolMessage("Start"); //新立文件File.sour
    FileStream stream = new FileStream("File.sour", FileMode.OpenOrCreate, FileAccess.ReadWrite,FileShare.ReadWrite,1024,true); byte[] bytes = new byte[16384]; string message = "An operating-system ThreadId has no fixed relationship........"; bytes = Encoding.Unicode.GetBytes(message); //啟動異步寫入
    stream.BeginWrite(bytes, 0, (int)bytes.Length,new AsyncCallback(Callback),stream); stream.Flush(); Console.ReadKey(); } static void Callback(IAsyncResult result) { //顯示線程池現(xiàn)狀
    Thread.Sleep(200); ThreadPoolMessage("AsyncCallback"); //結束異步寫入
    FileStream stream = (FileStream)result.AsyncState; stream.EndWrite(result); stream.Close(); } //顯示線程池現(xiàn)狀
    static void ThreadPoolMessage(string data) { int a, b; ThreadPool.GetAvailableThreads(out a, out b); string message = string.Format("{0}\n CurrentThreadId is {1}\n "+ "WorkerThreads is:{2} CompletionPortThreads is :{3}", data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString()); Console.WriteLine(message); } }

    由輸出結果可以看到,在使用FileStream.BeginWrite方法后,系統(tǒng)將自動啟動CLR線程池中I/O線程。


     

    5.1.2 異步讀取

    FileStream 中包含 BeginRead 與 EndRead 可以異步調(diào)用I/O線程進行讀取。

    public override IAsyncResult BeginRead ( byte[] array,int offset,int numBytes, AsyncCallback userCallback,Object stateObject)
    public override int EndRead(IAsyncResult asyncResult)

     

    其使用方式與BeginWrite和EndWrite相似,AsyncCallback用于綁定回調(diào)函數(shù); Object用于傳遞外部數(shù)據(jù)。在回調(diào)函數(shù)只需要使用IAsyncResut.AsyncState就可獲取外部數(shù)據(jù)。EndWrite 方法會返回從流讀取到的字節(jié)數(shù)量。

    首先定義 FileData 類,里面包含F(xiàn)ileStream對象,byte[] 數(shù)組和長度。然后把FileData對象作為外部數(shù)據(jù)傳到回調(diào)函數(shù),在回調(diào)函數(shù)中,把IAsyncResult.AsyncState強制轉(zhuǎn)換為 FileData,然后通過FileStream.EndRead(IAsyncResult)結束讀取。最后比較一下長度,若讀取到的長度與輸入的數(shù)據(jù) 長度不一至,則拋出異常。

     1      class Program
     2      {
     3          public class FileData
     4          {
     5              public FileStream Stream;
     6              public int Length;
     7              public byte[] ByteData;
     8          }
     9  
    10          static void Main(string[] args)
    11          {       
    12              //把線程池的最大值設置為1000
    13 ThreadPool.SetMaxThreads(1000, 1000); 14 ThreadPoolMessage("Start"); 15 ReadFile(); 16 17 Console.ReadKey(); 18 } 19 20 static void ReadFile() 21 { 22 byte[] byteData=new byte[80961024]; 23 FileStream stream = new FileStream("File1.sour", FileMode.OpenOrCreate, 24 FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true); 25 26 //把FileStream對象,byte[]對象,長度等有關數(shù)據(jù)綁定到FileData對象中,以附帶屬性方式送到回調(diào)函數(shù)
    27 FileData fileData = new FileData(); 28 fileData.Stream = stream; 29 fileData.Length = (int)stream.Length; 30 fileData.ByteData = byteData; 31 32 //啟動異步讀取
    33 stream.BeginRead(byteData, 0, fileData.Length, new AsyncCallback(Completed), fileData); 34 } 35 36 static void Completed(IAsyncResult result) 37 { 38 ThreadPoolMessage("Completed"); 39 40 //把AsyncResult.AsyncState轉(zhuǎn)換為FileData對象,以FileStream.EndRead完成異步讀取
    41 FileData fileData = (FileData)result.AsyncState; 42 int length=fileData.Stream.EndRead(result); 43 fileData.Stream.Close(); 44 45 //如果讀取到的長度與輸入長度不一致,則拋出異常
    46 if (length != fileData.Length) 47 throw new Exception("Stream is not complete!"); 48 49 string data=Encoding.ASCII.GetString(fileData.ByteData, 0, fileData.Length); 50 Console.WriteLine(data.Substring(2,22)); 51 } 52 53 //顯示線程池現(xiàn)狀
    54 static void ThreadPoolMessage(string data) 55 { 56 int a, b; 57 ThreadPool.GetAvailableThreads(out a, out b); 58 string message = string.Format("{0}\n CurrentThreadId is {1}\n "+ 59 "WorkerThreads is:{2} CompletionPortThreads is :{3}", 60 data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString()); 61 Console.WriteLine(message); 62 } 63 64 }

    由輸出結果可以看到,在使用FileStream.BeginRead方法后,系統(tǒng)將自動啟動CLR線程池中I/O線程。

     

    注意:如果你看到的測試結果正好相反:工作者線程為999,I/O線程為1000,這是因為FileStream的文件容量小于緩沖值1024所致的。此時文件將會一次性讀取或?qū)懭,而系統(tǒng)將啟動工作者線程而非I/O線程來處理回調(diào)函數(shù)。

     

     

    5.2 異步操作TCP/IP套接字

    在介紹 TCP/IP 套接字前先簡單介紹一下 NetworkStream 類,它是用于網(wǎng)絡訪問的基礎數(shù)據(jù)流。 NetworkStream 提供了好幾個方法控制套接字數(shù)據(jù)的發(fā)送與接收, 其中BeginRead、EndRead、BeginWrite、EndWrite 能夠?qū)崿F(xiàn)異步操作,而且異步線程是來自于CLR線程池的I/O線程。

    public override int ReadByte ()
    public override int Read (byte[] buffer,int offset, int size)

    public override void WriteByte (byte value)
    public override void Write (byte[] buffer,int offset, int size)

    public override IAsyncResult BeginRead (byte [] buffer, int offset, int size,  AsyncCallback callback, Object state )
    public override int EndRead(IAsyncResult result)

    public override IAsyncResult BeginWrite (byte [] buffer, int offset, int size,  AsyncCallback callback, Object state )
    public override void EndWrite(IAsyncResult result)

     

    若要創(chuàng)建 NetworkStream,必須提供已連接的 Socket。而在.NET中使用TCP/IP套接字不需要直接與Socket打交道,因為.NET把Socket的大部分操作都放在 System.Net.TcpListener和System.Net.Sockets.TcpClient里面,這兩個類大大地簡化了Socket的操 作。一般套接字對象Socket包含一個Accept()方法,此方法能產(chǎn)生阻塞來等待客戶端的請求,而在TcpListener類里也包含了一個相似的 方法 public TcpClient AcceptTcpClient()用于等待客戶端的請求。此方法將會返回一個TcpClient 對象,通過 TcpClient 的 public NetworkStream GetStream()方法就能獲取NetworkStream對象,控制套接字數(shù)據(jù)的發(fā)送與接收。

     

    下面以一個例子說明異步調(diào)用TCP/IP套接字收發(fā)數(shù)據(jù)的過程。

    首先在服務器端建立默認地址127.0.0.1用于收發(fā)信息,使用此地址與端口500新建TcpListener對象,調(diào)用TcpListener.Start 偵聽傳入的連接請求,再使用一個死循環(huán)來監(jiān)聽信息。

    在ChatClient類包括有接收信息與發(fā)送信息兩個功能:當接收到客戶端請求時,它會利 用 NetworkStream.BeginRead 讀取客戶端信息,并在回調(diào)函數(shù)ReceiveAsyncCallback中輸出信息內(nèi)容,若接收到的信息的大小小于1時,它將會拋出一個異常。當信息成功 接收后,再使用 NetworkStream.BeginWrite 方法回饋信息到客戶端

         class Program
         {
             static void Main(string[] args)
             {
                 //設置CLR線程池最大線程數(shù)
    ThreadPool.SetMaxThreads(1000, 1000); //默認地址為127.0.0.1
    IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); TcpListener tcpListener = new TcpListener(ipAddress, 500); tcpListener.Start(); //以一個死循環(huán)來實現(xiàn)監(jiān)聽
    while (true) { //調(diào)用一個ChatClient對象來實現(xiàn)監(jiān)聽
    ChatClient chatClient = new ChatClient(tcpListener.AcceptTcpClient()); } } } public class ChatClient { static TcpClient tcpClient; static byte[] byteMessage; static string clientEndPoint; public ChatClient(TcpClient tcpClient1) { tcpClient = tcpClient1; byteMessage = new byte[tcpClient.ReceiveBufferSize]; //顯示客戶端信息
    clientEndPoint = tcpClient.Client.RemoteEndPoint.ToString(); Console.WriteLine("Client's endpoint is " + clientEndPoint); //使用NetworkStream.BeginRead異步讀取信息
    NetworkStream networkStream = tcpClient.GetStream(); networkStream.BeginRead(byteMessage, 0, tcpClient.ReceiveBufferSize, new AsyncCallback(ReceiveAsyncCallback), null); } public void ReceiveAsyncCallback(IAsyncResult iAsyncResult) { //顯示CLR線程池狀態(tài)
    Thread.Sleep(100); ThreadPoolMessage("\nMessage is receiving"); //使用NetworkStream.EndRead結束異步讀取
    NetworkStream networkStreamRead = tcpClient.GetStream(); int length=networkStreamRead.EndRead(iAsyncResult); //如果接收到的數(shù)據(jù)長度少于1則拋出異常
    if (length < 1) { tcpClient.GetStream().Close(); throw new Exception("Disconnection!"); } //顯示接收信息
    string message = Encoding.UTF8.GetString(byteMessage, 0, length); Console.WriteLine("Message:" + message); //使用NetworkStream.BeginWrite異步發(fā)送信息
    byte[] sendMessage = Encoding.UTF8.GetBytes("Message is received!"); NetworkStream networkStreamWrite=tcpClient.GetStream(); networkStreamWrite.BeginWrite(sendMessage, 0, sendMessage.Length, new AsyncCallback(SendAsyncCallback), null); } //把信息轉(zhuǎn)換成二進制數(shù)據(jù),然后發(fā)送到客戶端
    public void SendAsyncCallback(IAsyncResult iAsyncResult) { //顯示CLR線程池狀態(tài)
    Thread.Sleep(100); ThreadPoolMessage("\nMessage is sending"); //使用NetworkStream.EndWrite結束異步發(fā)送
    tcpClient.GetStream().EndWrite(iAsyncResult); //重新監(jiān)聽
    tcpClient.GetStream().BeginRead(byteMessage, 0, tcpClient.ReceiveBufferSize, new AsyncCallback(ReceiveAsyncCallback), null); } //顯示線程池現(xiàn)狀
    static void ThreadPoolMessage(string data) { int a, b; ThreadPool.GetAvailableThreads(out a, out b); string message = string.Format("{0}\n CurrentThreadId is {1}\n " + "WorkerThreads is:{2} CompletionPortThreads is :{3}\n", data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString()); Console.WriteLine(message); } }

    而在客戶端只是使用簡單的開發(fā)方式,利用TcpClient連接到服務器端,然后調(diào)用NetworkStream.Write方法發(fā)送信息,最后調(diào)用NetworkStream.Read方法讀取回饋信息

     1         static void Main(string[] args)
     2         {
     3             //連接服務端
    4 TcpClient tcpClient = new TcpClient("127.0.0.1", 500); 5 6 //發(fā)送信息
    7 NetworkStream networkStream = tcpClient.GetStream(); 8 byte[] sendMessage = Encoding.UTF8.GetBytes("Client request connection!"); 9 networkStream.Write(sendMessage, 0, sendMessage.Length); 10 networkStream.Flush(); 11 12 //接收信息
    13 byte[] receiveMessage=new byte[1024]; 14 int count=networkStream.Read(receiveMessage, 0,1024); 15 Console.WriteLine(Encoding.UTF8.GetString(receiveMessage)); 16 Console.ReadKey(); 17 }

    注意觀察運行結果,服務器端的異步操作線程都是來自于CLR線程池的I/O線程


     

    5.3 異步WebRequest

    System.Net.WebRequest 是 .NET 為實現(xiàn)訪問 Internet 的 “請求/響應模型” 而開發(fā)的一個 abstract 基類, 它 主要有三個子類:FtpWebRequest、HttpWebRequest、FileWebRequest。當使用 WebRequest.Create(string uri)創(chuàng)建對象時,應用程序就可以根據(jù)請求協(xié)議判斷實現(xiàn)類來進行操作。FileWebRequest、FtpWebRequest、 HttpWebRequest 各有其作用:FileWebRequest 使用 “file://路徑” 的URI方式實現(xiàn)對本地資源和內(nèi)部文件的請求/響應、FtpWebRequest 使用FTP文件傳輸協(xié)議實現(xiàn)文件請求/響應、HttpWebRequest 用于處理HTTP的頁面請求/響應。由于使用方法相類似,下面就以常用的HttpWebRequest為例子介紹一下異步WebRequest的使用方法。

    在使用ASP.NET開發(fā)網(wǎng)站的時候,往往會忽略了HttpWebRequest的使用,因為開發(fā) 都假設客戶端是使用瀏覽器等工具去閱讀頁面的。但如果你對REST開發(fā)方式有所了解,那對 HttpWebRequest 就應該非常熟悉。它可以在路徑參數(shù)、頭文件、頁面主體、Cookie 等多處地方加入請求條件,然后對回復數(shù)據(jù)進行適當處理。HttpWebRequest 包含有以下幾個常用方法用于處理請求/響應:

    public override Stream GetRequestStream ()
    public override WebResponse GetResponse ()

    public override IAsyncResult BeginGetRequestStream ( AsyncCallback callback, Object state )
    public override Stream EndGetRequestStream ( IAsyncResult asyncResult )
    public override IAsyncResult BeginGetResponse ( AsyncCallback callback, Object state )
    public override WebResponse EndGetResponse ( IAsyncResult asyncResult )

    其中BeginGetRequestStream、EndGetRequestStream 用于異步向HttpWebRequest對象寫入請求信息;  BeginGetResponse、EndGetResponse 用于異步發(fā)送頁面請求并獲取返回信息。使用異步方式操作Internet的“請求/響應”,避免主線程長期處于等待狀態(tài),而操作期間異步線程是來自CLR 線程池的I/O線程。

    注意:請求與響應不能使用同步與異步混合開發(fā)模式,即當請求寫入使用GetRequestStream同步模式,即使響應使用BeginGetResponse異步方法,操作也與GetRequestStream方法在于同一線程內(nèi)。

    下面以簡單的例子介紹一下異步請求的用法。

    首先為Person類加上可序列化特性,在服務器端建立Hanlder.ashx,通過Request.InputStream 獲取到請求數(shù)據(jù)并把數(shù)據(jù)轉(zhuǎn)化為String對象,此實例中數(shù)據(jù)是以 “Id:1” 的形式實現(xiàn)傳送的。然后根據(jù)Id查找對應的Person對象,并把Person對象寫入Response.OutStream 中返還到客戶端。

    在客戶端先把 HttpWebRequird.Method 設置為 "post",使用異步方式通過BeginGetRequireStream獲取請求數(shù)據(jù)流,然后寫入請求數(shù)據(jù) “Id:1”。再使用異步方法BeginGetResponse 獲取回復數(shù)據(jù),最后把數(shù)據(jù)反序列化為Person對象顯示出來。

    注意:HttpWebRequire.Method默認為get,在寫入請求前必須把HttpWebRequire.Method設置為post,否則在使用BeginGetRequireStream 獲取請求數(shù)據(jù)流的時候,系統(tǒng)就會發(fā)出 “無法發(fā)送具有此謂詞類型的內(nèi)容正文" 的異常。

    Model

     namespace Model
     {
         [Serializable]
         public class Person
         {
             public int ID
             {
                 get;
                 set;
             }
             public string Name
             {
                 get;
                 set;
             }
             public int Age
             {
                 get;
                 set;
             }
         }
     }


    服務器端

     1 public class Handler : IHttpHandler {
     2 
     3     public void ProcessRequest(HttpContext context)
     4     {
     5         //把信息轉(zhuǎn)換為String,找出輸入條件Id
    6 byte[] bytes=new byte[1024]; 7 int length=context.Request.InputStream.Read(bytes,0,1024); 8 string condition = Encoding.Default.GetString(bytes); 9 int id = int.Parse(condition.Split(new string[] { ":" }, 10 StringSplitOptions.RemoveEmptyEntries)[1]); 11 12 //根據(jù)Id查找對應Person對象
    13 var person = GetPersonList().Where(x => x.ID == id).First(); 14 15 //所Person格式化為二進制數(shù)據(jù)寫入OutputStream
    16 BinaryFormatter formatter = new BinaryFormatter(); 17 formatter.Serialize(context.Response.OutputStream, person); 18 } 19 20 //模擬源數(shù)據(jù)
    21 private IList<Person> GetPersonList() 22 { 23 var personList = new List<Person>(); 24 25 var person1 = new Person(); 26 person1.ID = 1; 27 person1.Name = "Leslie"; 28 person1.Age = 30; 29 personList.Add(person1); 30 ........... 31 return personList; 32 } 33 34 public bool IsReusable 35 { 36 get { return true;} 37 } 38 }

    客戶端

         class Program
         {
             static void Main(string[] args)
             {
                 ThreadPool.SetMaxThreads(1000, 1000);
                 Request();
                 Console.ReadKey();
             }
     
             static void Request()
             {
                 ThreadPoolMessage("Start"); 
                 //使用WebRequest.Create方法建立HttpWebRequest對象
    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create( "http://localhost:5700/Handler.ashx"); webRequest.Method = "post"; //對寫入數(shù)據(jù)的RequestStream對象進行異步請求
    IAsyncResult result=webRequest.BeginGetRequestStream( new AsyncCallback(EndGetRequestStream),webRequest); } static void EndGetRequestStream(IAsyncResult result) { ThreadPoolMessage("RequestStream Complete"); //獲取RequestStream
    HttpWebRequest webRequest = (HttpWebRequest)result.AsyncState; Stream stream=webRequest.EndGetRequestStream(result); //寫入請求條件
    byte[] condition = Encoding.Default.GetBytes("Id:1"); stream.Write(condition, 0, condition.Length); //異步接收回傳信息
    IAsyncResult responseResult = webRequest.BeginGetResponse( new AsyncCallback(EndGetResponse), webRequest); } static void EndGetResponse(IAsyncResult result) { //顯出線程池現(xiàn)狀
    ThreadPoolMessage("GetResponse Complete"); //結束異步請求,獲取結果
    HttpWebRequest webRequest = (HttpWebRequest)result.AsyncState; WebResponse webResponse = webRequest.EndGetResponse(result); //把輸出結果轉(zhuǎn)化為Person對象
    Stream stream = webResponse.GetResponseStream(); BinaryFormatter formatter = new BinaryFormatter(); var person=(Person)formatter.Deserialize(stream); Console.WriteLine(string.Format("Person Id:{0} Name:{1} Age:{2}", person.ID, person.Name, person.Age)); } //顯示線程池現(xiàn)狀
    static void ThreadPoolMessage(string data) { int a, b; ThreadPool.GetAvailableThreads(out a, out b); string message = string.Format("{0}\n CurrentThreadId is {1}\n " + "WorkerThreads is:{2} CompletionPortThreads is :{3}\n", data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString()); Console.WriteLine(message); } }

    從運行結果可以看到,BeginGetRequireStream、BeginGetResponse方法是使用CLR線程池的I/O線程。



    5.4 異步調(diào)用WebService

    相比TCP/IP套接字,在使用WebService的時候,服務器端需要更復雜的操作處理,使用時間往往會更長。為了避免客戶端長期處于等待狀態(tài),在配置服務引用時選擇 “生成異步操作”,系統(tǒng)可以自動建立異步調(diào)用的方式。

    以.NET 2.0以前,系統(tǒng)都是使用ASMX來設計WebService,而近年來WCF可說是火熱登場,下面就以WCF為例子簡單介紹一下異步調(diào)用WebService的例子。

    由于系統(tǒng)可以自動生成異步方法,使用起來非常簡單,首先在服務器端建立服務 ExampleService,里面包含方法Method。客戶端引用此服務時,選擇 “生成異步操作”。然后使用 BeginMethod 啟動異步方法, 在回調(diào)函數(shù)中調(diào)用EndMethod結束異步調(diào)用。

    服務端

     1      [ServiceContract]
     2      public interface IExampleService
     3      {
     4          [OperationContract]
     5          string Method(string name);
     6      }
     7  
     8      public class ExampleService : IExampleService
     9      {
    10          public string Method(string name)
    11          {
    12              return "Hello " + name;
    13          }
    14      }
    15  
    16      class Program
    17      {
    18          static void Main(string[] args)
    19          {
    20              ServiceHost host = new ServiceHost(typeof(ExampleService));
    21              host.Open();
    22              Console.ReadKey();
    23              host.Close();
    24           }
    25      }
    26  
    27  <configuration>
    28      <system.serviceModel>
    29          <services>
    30              <service name="Example.ExampleService">
    31                  <endpoint address="" binding="wsHttpBinding" contract="Example.IExampleService">
    32                      <identity>
    33                          <dns value="localhost" />
    34                      </identity>
    35                  </endpoint>
    36                  <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    37                  <host>
    38                      <baseAddresses>
    39                          <add baseAddress="http://localhost:7200/Example/ExampleService/" />
    40                      </baseAddresses>
    41                  </host>
    42              </service>
    43          </services>
    44      </system.serviceModel>
    45  </configuration>

    客戶端

          class Program
          {
              static void Main(string[] args)
              {
                  //設置最大線程數(shù)
    ThreadPool.SetMaxThreads(1000, 1000); ThreadPoolMessage("Start"); //建立服務對象,異步調(diào)用服務方法
    ExampleServiceReference.ExampleServiceClient exampleService = new ExampleServiceReference.ExampleServiceClient(); exampleService.BeginMethod("Leslie",new AsyncCallback(AsyncCallbackMethod), exampleService); Console.ReadKey(); } static void AsyncCallbackMethod(IAsyncResult result) { Thread.Sleep(1000); ThreadPoolMessage("Complete"); ExampleServiceReference.ExampleServiceClient example = (ExampleServiceReference.ExampleServiceClient)result.AsyncState; string data=example.EndMethod(result); Console.WriteLine(data); } //顯示線程池現(xiàn)狀
    static void ThreadPoolMessage(string data) { int a, b; ThreadPool.GetAvailableThreads(out a, out b); string message = string.Format("{0}\n CurrentThreadId is {1}\n " + "WorkerThreads is:{2} CompletionPortThreads is :{3}\n", data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString()); Console.WriteLine(message); } } <configuration> <system.serviceModel> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IExampleService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Message"> <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" /> <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" /> </security> </binding> </wsHttpBinding> </bindings> <client> <endpoint address="http://localhost:7200/Example/ExampleService/" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IExampleService" contract="ExampleServiceReference.IExampleService" name="WSHttpBinding_IExampleService"> <identity> <dns value="localhost" /> </identity> </endpoint> </client> </system.serviceModel> </configuration>

    注意觀察運行結果,異步調(diào)用服務時,回調(diào)函數(shù)都是運行于CLR線程池的I/O線程當中。
    億恩-天使(QQ:530997) 電話 037160135991 服務器租用,托管歡迎咨詢。


    本文出自:億恩科技【mszdt.com】

    服務器租用/服務器托管中國五強!虛擬主機域名注冊頂級提供商!15年品質(zhì)保障!--億恩科技[ENKJ.COM]

  • 您可能在找
  • 億恩北京公司:
  • 經(jīng)營性ICP/ISP證:京B2-20150015
  • 億恩鄭州公司:
  • 經(jīng)營性ICP/ISP/IDC證:豫B1.B2-20060070
  • 億恩南昌公司:
  • 經(jīng)營性ICP/ISP證:贛B2-20080012
  • 服務器/云主機 24小時售后服務電話:0371-60135900
  • 虛擬主機/智能建站 24小時售后服務電話:0371-60135900
  • 專注服務器托管17年
    掃掃關注-微信公眾號
    0371-60135900
    Copyright© 1999-2019 ENKJ All Rights Reserved 億恩科技 版權所有  地址:鄭州市高新區(qū)翠竹街1號總部企業(yè)基地億恩大廈  法律顧問:河南亞太人律師事務所郝建鋒、杜慧月律師   京公網(wǎng)安備41019702002023號
      1
     
     
     
     

    0371-60135900
    7*24小時客服服務熱線