Chinaunix首页 | 论坛 | 博客
  • 博客访问: 490842
  • 博文数量: 33
  • 博客积分: 4168
  • 博客等级: 上校
  • 技术积分: 675
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-26 20:21
文章分类

全部博文(33)

文章存档

2013年(8)

2012年(2)

2011年(7)

2010年(1)

2009年(4)

2008年(11)

分类: 嵌入式

2011-04-11 12:54:28

WCF的异步服务编程,必须创建一个IAsyncResult的自定义实现:
 
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;

  6. class UniversalAsyncResult : IAsyncResult, IDisposable
  7. {
  8.     // 存储回调和状态

  9.     AsyncCallback callback;
  10.     object state;

  11.     // For the implementation of IAsyncResult.AsyncCallback

  12.     volatile ManualResetEvent waithandle;

  13.     // 线程同步对象

  14.     object guard = new object();

  15.     // 完成标志,设置为true就表示完成

  16.     volatile bool complete;

  17.     public UniversalAsyncResult(AsyncCallback callback, object state)
  18.     {
  19.         this.callback = callback;
  20.         this.state = state;
  21.     }

  22.     public void Complete()
  23.     {
  24.         // flag as complete

  25.         complete = true;

  26.         // signal the event object

  27.         if (waithandle != null)
  28.         {
  29.             waithandle.Set();
  30.         }

  31.         // Fire callback to signal the call is complete

  32.         if (callback != null)
  33.         {
  34.             callback(this);
  35.         }
  36.     }

  37.     #region IAsyncResult Members
  38.     public object AsyncState
  39.     {
  40.         get { return state; }
  41.     }

  42.     // Use double check locking for efficient lazy allocation of the event object

  43.     public WaitHandle AsyncWaitHandle
  44.     {
  45.         get
  46.         {
  47.             if (waithandle == null)
  48.             {
  49.                 lock (guard)
  50.                 {
  51.                     if (waithandle == null)
  52.                     {
  53.                         waithandle = new ManualResetEvent(false);

  54.                         if (complete)
  55.                         {
  56.                             waithandle.Set();
  57.                         }
  58.                     }
  59.                 }
  60.             }
  61.             return waithandle;
  62.         }
  63.     }

  64.     public bool CompletedSynchronously
  65.     {
  66.         get { return false; }
  67.     }

  68.     public bool IsCompleted
  69.     {
  70.         get { return complete; }
  71.     }
  72.     #endregion

  73.     #region IDisposable Members
  74.     
  75.     public void Dispose()
  76.     {
  77.         if (waithandle != null)
  78.         {
  79.             waithandle.Close();
  80.         }
  81.     }
  82.     #endregion
  83. }
应用==========>
 
服务端:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.ServiceModel;
  5. using System.Data.SqlClient;
  6. using System.Data;
  7. using System.Threading;

  8. namespace Service
  9. {
  10.     class Program
  11.     {
  12.         static void Main(string[] args)
  13.         {
  14.             using (ServiceHost host = new ServiceHost(typeof(Service)))
  15.             {
  16.                 host.Open();

  17.                 Console.WriteLine("Async Service Ready ...");
  18.                 Console.ReadLine();
  19.             }
  20.         }
  21.     }

  22.     [ServiceContract]
  23.     interface IGetData
  24.     {
  25.         // This pair of methods are bound together as WCF is aware of the async pattern

  26.         [OperationContract(AsyncPattern=true)]
  27.         IAsyncResult BeginGetData(AsyncCallback cb, object state);
  28.         string[] EndGetData(IAsyncResult iar);
  29.     }

  30.     class Service : IGetData
  31.     {
  32.         SqlCommand cmd;
  33.         SqlConnection conn;
  34.         DataAsyncResult dar;

  35.         // This connection string sets up the connection for asynchronous process which is supported by SQL2005

  36.         static readonly string CONN_STR = @"Server=.\sqlexpress; database=slowdb; integrated security=SSPI; Asynchronous Processing=true";

  37.         // This is the async pattern begin method that is passed a callback from the WCF infrastructure

  38.         public IAsyncResult BeginGetData(AsyncCallback cb, object state)
  39.         {
  40.             // Create own async result type call object to let WCF know when the call has completed and so

  41.             // when it can call the EndGetData method

  42.             dar = new DataAsyncResult(cb, state);

  43.             // Create the connection annd command

  44.             conn = new SqlConnection(CONN_STR);
  45.             cmd = conn.CreateCommand();
  46.             cmd.CommandText = "SlowSproc";
  47.             cmd.CommandType = CommandType.StoredProcedure;

  48.             conn.Open();

  49.             // Process the query asynchronously

  50.             // this will take place using IO completion ports

  51.             // so a thread is not being used while the query is running

  52.             cmd.BeginExecuteReader(Callback, null);

  53.             // return the call object to the WCF infrastructure

  54.             return dar;
  55.         }

  56.         // End method cleans up and sends back the results

  57.         public string[] EndGetData(IAsyncResult iar)
  58.         {
  59.             dar.Dispose();
  60.             return data.ToArray();
  61.         }

  62.         // Called when the async query completes

  63.         void Callback( IAsyncResult iar )
  64.         {
  65.             List<string> results = new List<string>();

  66.             // process the list of results

  67.             using (SqlDataReader reader = cmd.EndExecuteReader(iar))
  68.             {

  69.                 while( reader.Read() )
  70.                 {
  71.                     results.Add((string)reader["val"]);
  72.                 }
  73.             }

  74.             // cache the results

  75.             data = results;

  76.             // clean up the connection which is no longer required

  77.             conn.Dispose();

  78.             // Tell the call object that the call is now complete

  79.             dar.Complete();
  80.         }

  81.         List<string> data;
  82.     }
 客户端:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Client.ServiceReference;

  6. namespace Client
  7. {
  8.     class Program
  9.     {
  10.         static void Main(string[] args)
  11.         {
  12.             GetDataClient proxy = new GetDataClient();

  13.             string[] res = proxy.GetData();

  14.             foreach (var item in res)
  15.             {
  16.                 Console.WriteLine(item);
  17.             }
  18.         }
  19.     }
  20. }
 
阅读(1648) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~