C# 異步編程學習(一)
阿新 • • 發佈:2018-06-23
apm 結果 mic public b- num row worker inf
異步 編程 可在 等待 某個 任務 完成時, 避免 線程 的 占用, 但要 想 正確地 實現 編程, 仍然 十分 傷腦筋。
. NET Framework 中, 有三種 不同 的 模型 來 簡化 異步 編程。
.NET 1. x 中的 BeginFoo/ EndFoo 方法, 使用 IAsyncResult 和 AsyncCallback 來 傳播 結果。
.NET 2. 0 中 基於 事件 的 異步 模式, 使用 BackgroundWorker 和 WebClient 實現。
.NET 4 引入 並由. NET 4. 5 擴展 的 任務 並行 庫( TPL)。
(一)APM(異步編程模型)C#版本為1.1
APM異步編程模型最具代表性的特點是:一個異步功能由以Begin開頭、End開頭的兩個方法組成。Begin開頭的方法表示啟動異步功能的執行,End開頭的方法表示等待異步功能執行結束並返回執行結果;
模擬實現:
public class Worker { public int A { get; set; } public int B { get; set; } private int R { get; set; } ManualResetEvent et; public void BeginWork(Action action) { etView Code= new ManualResetEvent(false); new Thread(() => { R = A + B; Thread.Sleep(1000); et.Set(); if(null != action) { action(); } }).Start(); }public int EndWork() { if(null == et) { throw new Exception("調用EndWork前,需要先調用BeginWork"); } else { et.WaitOne(); return R; } } }
調用代碼:
static void Main(string[] args) { Worker w = new Worker(); w.BeginWork(()=> { Console.WriteLine("Thread Id:{0},Count:{1}", Thread.CurrentThread.ManagedThreadId, w.EndWork()); }); Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId); Console.ReadLine(); }View Code
標準的APM模型如何實現異步編程:
IAsyncResult接口
IAsyncResult接口定義了異步功能的狀態,該接口具體屬性及含義如下:
// 表示異步操作的狀態。 [ComVisible(true)] public interface IAsyncResult { // // 摘要: // 獲取一個值,該值指示異步操作是否已完成。 // // 返回結果: // 如果操作已完成,則為 true;否則為 false。 bool IsCompleted { get; } // // 摘要: // 獲取用於等待異步操作完成的 System.Threading.WaitHandle。 // // 返回結果: // 用於等待異步操作完成的 System.Threading.WaitHandle。 WaitHandle AsyncWaitHandle { get; } // // 摘要: // 獲取一個用戶定義的對象,該對象限定或包含有關異步操作的信息。 // // 返回結果: // 一個用戶定義的對象,限定或包含有關異步操作的信息。 object AsyncState { get; } // // 摘要: // 獲取一個值,該值指示異步操作是否同步完成。 // // 返回結果: // 如果異步操作同步完成,則為 true;否則為 false。 bool CompletedSynchronously { get; } }View Code
接口的實現:
public class NewWorker { public class WorkerAsyncResult : IAsyncResult { AsyncCallback callback; public WorkerAsyncResult(int a,int b, AsyncCallback callback, object asyncState) { A = a; B = b; state = asyncState; this.callback = callback; new Thread(Count).Start(this); } public int A { get; set; } public int B { get; set; } public int R { get; private set; } private object state; public object AsyncState { get { return state; } } private ManualResetEvent waitHandle; public WaitHandle AsyncWaitHandle { get { if (null == waitHandle) { waitHandle = new ManualResetEvent(false); } return waitHandle; } } private bool completedSynchronously; public bool CompletedSynchronously { get { return completedSynchronously; } } private bool isCompleted; public bool IsCompleted { get { return isCompleted; } } private static void Count(object state) { var result = state as WorkerAsyncResult; result.R = result.A + result.B; Thread.Sleep(1000); result.completedSynchronously = false; result.isCompleted = true; ((ManualResetEvent)result.AsyncWaitHandle).Set(); if (result.callback != null) { result.callback(result); } } } public int Num1 { get; set; } public int Num2 { get; set; } public IAsyncResult BeginWork(AsyncCallback userCallback, object asyncState) { IAsyncResult result = new WorkerAsyncResult(Num1,Num2,userCallback, asyncState); return result; } public int EndWork(IAsyncResult result) { WorkerAsyncResult r = result as WorkerAsyncResult; r.AsyncWaitHandle.WaitOne(); return r.R; } }View Code
調用:
static void Main(string[] args) { NewWorker w2 = new NewWorker(); w2.Num1 = 10; w2.Num2 = 12; IAsyncResult r = null; r = w2.BeginWork((obj) => { Console.WriteLine("Thread Id:{0},Count:{1}",Thread.CurrentThread.ManagedThreadId, w2.EndWork(r)); }, null); Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId); Console.ReadLine(); }View Code
Delegate異步編程(APM 標準實現)
public class NewWorker2 { Func<int, int, int> action; public NewWorker2() { action = new Func<int, int, int>(Work); } public IAsyncResult BeginWork(AsyncCallback callback, object state) { dynamic obj = state; return action.BeginInvoke(obj.A, obj.B, callback, this); } public int EndWork(IAsyncResult asyncResult) { try { return action.EndInvoke(asyncResult); } catch (Exception ex) { throw ex; } } private int Work(int a, int b) { Thread.Sleep(1000); return a + b; } }View Code
static void Main(string[] args) { NewWorker2 w2 = new NewWorker2(); IAsyncResult r = null; r = w2.BeginWork((obj) => { Console.WriteLine("Thread Id:{0},Count:{1}", Thread.CurrentThread.ManagedThreadId, w2.EndWork(r)); }, new { A = 10, B = 11 }); Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId); Console.ReadLine(); }View Code
學習網站:https://blog.csdn.net/nginxs/article/details/77917172
C# 異步編程學習(一)