亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

簡單實現C#異步操作

2020-01-24 01:16:51
字體:
來源:轉載
供稿:網友

在.net4.0以后異步操作,并行計算變得異常簡單,但是由于公司項目開發基于.net3.5所以無法用到4.0的并行計算以及Task等異步編程。因此,為了以后更方便的進行異步方式的開發,我封裝實現了異步編程框架,通過BeginInvoke、EndInvoke的方式實現異步編程。

一、框架結構

整個框架包括四個部分

1、基類抽象Opeartor
我把每個異步執行過程稱為一個Operate,因此需要一個Opeartor去執行
2、FuncAsync
異步的Func
3、ActionAsync
異步的Action
4、Asynchorus
對ActionAsync和FuncAsync的封裝

Operator
Operator是一個抽象類,實現了IOperationAsync和IContinueWithAsync兩個接口。
IOperationAsync實現了異步操作,IContinueWithAsync實現了類似于Task的ContinueWith方法,在當前異步操作完成后繼續進行的操作

IOperationAsync接口詳解

public interface IOperationAsync{  IAsyncResult Invoke();  void Wait();  void CompletedCallBack(IAsyncResult ar);  void CatchException(Exception exception);}
  • Invoke():異步方法的調用
  • Wait():等待異步操作執行
  • CompletedCallBack():操作完成回調
  • CatchException():抓取異常

IContinueWithAsync接口詳情

public interface IContinueWithAsync{  Operator Previous { get; set; }  Operator Next { get; set; }  Operator ContinueWithAsync(Action action);  Operator ContinueWithAsync<TParameter>(Action<TParameter> action, TParameter parameter);}

Previous:前一個操作
Next:下一個操作
ContinueWithAsync():異步繼續操作

public abstract class Operator : IOperationAsync, IContinueWithAsync{  public IAsyncResult Middle;  public readonly string Id;  public Exception Exception { get; private set; }  public Operator Previous { get; set; }  public Operator Next { get; set; }  protected Operator()  {    Id = Guid.NewGuid().ToString();  }  public abstract IAsyncResult Invoke();  protected void SetAsyncResult(IAsyncResult result)  {    this.Middle = result;  }  public virtual void Wait()  {    if (!Middle.IsCompleted) Middle.AsyncWaitHandle.WaitOne();  }  public virtual void CompletedCallBack(IAsyncResult ar)  {  }  public void CatchException(Exception exception)  {    this.Exception = exception;  }  protected Operator ContinueAsync()  {    if (Next != null) Next.Invoke();    return Next;  }  public virtual Operator ContinueWithAsync(Action action)  {    Next = new ActionAsync(action);    Next.Previous = this;    return Next;  }  public virtual Operator ContinueWithAsync<TParameter>(Action<TParameter> action, TParameter parameter)  {    Next = new ActionAsync<TParameter>(action, parameter);    Next.Previous = this;    return Next;  }  public virtual Operator ContinueWithAsync<TResult>(Func<TResult> func)  {    Next = new FuncAsync<TResult>();    Next.Previous = this;    return Next;  }  public virtual Operator ContinueWithAsync<TParameter, TResult>(Func<TParameter, TResult> func,    TParameter parameter)  {    Next = new FuncAsync<TParameter, TResult>(func, parameter);    Next.Previous = this;    return Next;  }}

無返回異步操作
ActionAsync

public class ActionAsync : Operator{  private readonly Action _action;  protected ActionAsync()  {  }  public ActionAsync(Action action)    : this()  {    this._action = action;  }  public override IAsyncResult Invoke()  {    var middle = _action.BeginInvoke(CompletedCallBack, null);    SetAsyncResult(middle);    return middle;  }  public override void CompletedCallBack(IAsyncResult ar)  {    try    {      _action.EndInvoke(ar);    }    catch (Exception exception)    {      this.CatchException(exception);    }    ContinueAsync();  }}public class ActionAsync<T> : ActionAsync{  public T Result;  private readonly Action<T> _action1;  protected readonly T Parameter1;  public ActionAsync()  {  }  public ActionAsync(T parameter)  {    this.Parameter1 = parameter;  }  public ActionAsync(Action<T> action, T parameter)  {    this._action1 = action;    this.Parameter1 = parameter;  }  public override IAsyncResult Invoke()  {    var result = _action1.BeginInvoke(Parameter1, CompletedCallBack, null);    SetAsyncResult(result);    return result;  }  public override void CompletedCallBack(IAsyncResult ar)  {    try    {      _action1.EndInvoke(ar);    }    catch (Exception exception)    {      this.CatchException(exception);    }    ContinueAsync();  }}

有返回異步
FuncAsync實現了IFuncOperationAsync接口

IFuncOperationAsync

public interface IFuncOperationAsync<T>{  void SetResult(T result);  T GetResult();}
  • SetResult(T result):異步操作完成設置返回值
  • GetResult():獲取返回值

1)、FuncAsync

public class FuncAsync<TResult> : Operator, IFuncOperationAsync<TResult>{private TResult _result;public TResult Result{  get  {    if (!Middle.IsCompleted || _result == null)    {      _result = GetResult();    }    return _result;  }}private readonly Func<TResult> _func1;public FuncAsync(){}public FuncAsync(Func<TResult> func){  this._func1 = func;}public override IAsyncResult Invoke(){  var result = _func1.BeginInvoke(CompletedCallBack, null);  SetAsyncResult(result);  return result;}public override void CompletedCallBack(IAsyncResult ar){  try  {    var result = _func1.EndInvoke(ar);    SetResult(result);  }  catch (Exception exception)  {    this.CatchException(exception);    SetResult(default(TResult));  }  ContinueAsync();}public virtual TResult GetResult(){  Wait();  return this._result;}public void SetResult(TResult result){  _result = result;}}public class FuncAsync<T1, TResult> : FuncAsync<TResult>{protected readonly T1 Parameter1;private readonly Func<T1, TResult> _func2;public FuncAsync(Func<T1, TResult> action, T1 parameter1)  : this(parameter1){  this._func2 = action;}protected FuncAsync(T1 parameter1)  : base(){  this.Parameter1 = parameter1;}public override IAsyncResult Invoke(){  var result = _func2.BeginInvoke(Parameter1, CompletedCallBack, null);  SetAsyncResult(result);  return result;}public override void CompletedCallBack(IAsyncResult ar){  try  {    var result = _func2.EndInvoke(ar);    SetResult(result);  }  catch (Exception exception)  {    CatchException(exception);    SetResult(default(TResult));  }  ContinueAsync();}}

Asynchronous 異步操作封裝
ActionAsync和FuncAsync為異步操作打下了基礎,接下來最重要的工作就是通過這兩個類執行我們的異步操作,為此我封裝了一個異步操作類
主要封裝了以下幾個部分:

  • WaitAll(IEnumerable<Operator> operations):等待所有操作執行完畢
  • WaitAny(IEnumerable<Operator> operations):等待任意操作執行完畢
  • ActionAsync
  • FuncAsync
  • ContinueWithAction
  • ContinueWithFunc

后面四個包含若干個重載,這里只是籠統的代表一個類型的方法
WaitAll

public static void WaitAll(IEnumerable<Operator> operations){foreach (var @operator in operations){  @operator.Wait();}}

WaitAny

public static void WaitAny(IEnumerable<Operator> operations){while (operations.All(o => !o.Middle.IsCompleted))  Thread.Sleep(100);}

等待時間可以自定義
ActionInvoke

public static Operator Invoke(Action action){Operator operation = new ActionAsync(action);operation.Invoke();return operation;}public static Operator Invoke<T>(Action<T> action, T parameter){Operator operation = new ActionAsync<T>(action, parameter);operation.Invoke();return operation;}public static Operator Invoke<T1, T2>(Action<T1, T2> action, T1 parameter1, T2 parameter2){Operator operation = new ActionAsync<T1, T2>(action, parameter1, parameter2);operation.Invoke();return operation;}

FuncInvoke

public static Operator Invoke<TResult>(Func<TResult> func){Operator operation = new FuncAsync<TResult>(func);operation.Invoke();return operation;}public static Operator Invoke<TParameter, TResult>(Func<TParameter, TResult> func, TParameter parameter){TParameter param = parameter;Operator operation = new FuncAsync<TParameter, TResult>(func, param);operation.Invoke();return operation;}public static Operator Invoke<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 parameter1, T2 parameter2){Operator operation = new FuncAsync<T1, T2, TResult>(func, parameter1, parameter2);operation.Invoke();return operation;}

ContinueWithAction

public static Operator ContinueWithAsync(IEnumerable<Operator>operators, Action action){return Invoke(WaitAll, operators)  .ContinueWithAsync(action);}public static Operator ContinueWithAsync<TParameter>(IEnumerable<Operator> operators, Action<TParameter> action, TParameter parameter){return Invoke(WaitAll, operators)  .ContinueWithAsync(action, parameter);}

ContinueWithFunc

public static Operator ContinueWithAsync<TResult>(IEnumerable<Operator> operators,Func<TResult> func){return Invoke(WaitAll, operators)  .ContinueWithAsync(func);}public static Operator ContinueWithAsync<TParameter, TResult>(IEnumerable<Operator> operators, Func<TParameter, TResult> func, TParameter parameter){return Invoke(WaitAll, operators)  .ContinueWithAsync(func, parameter);}

這里有個bug當調用ContinueWithAsync后無法調用Wait等待,本來Wait需要從前往后等待每個異步操作,但是測試了下不符合預期結果。不過理論上來說應該無需這樣操作,ContinueWithAsync只是為了當上一個異步操作執行完畢時繼續執行的異步操作,若要等待,那不如兩個操作放到一起,最后再等待依然可以實現。
前面的都是單步異步操作的調用,若需要對某集合進行某個方法的異步操作,可以foreach遍歷

public void ForeachAsync(IEnumerbale<string> parameters){  foreach(string p in parameters)  {    Asynchronous.Invoke(Tast,p);  }}public void Test(string parameter){  //TODO:做一些事}

每次都需要去手寫foreach,比較麻煩,因此實現類似于PLinq的并行計算方法實在有必要,不過有一點差別,PLinq是采用多核CPU進行并行計算,而我封裝的僅僅遍歷集合進行異步操作而已
ForeachAction

public static IEnumerable<Operator> Foreach<TParameter>(IEnumerable<TParameter> items, Action<TParameter> action){  return items.Select(t => Invoke(action, t)).ToList();}

ForeachFunc

public static IEnumerable<Operator> Foreach<TParameter, TResult>(IEnumerable<TParameter> items, Func<TParameter, TResult> func){  return items.Select(parameter => Invoke(func, parameter)).ToList();}

如何使用
無返回值異步方法調用

public void DoSomeThing(){//TODO:}

通過Asynchronous.Invoke(DoSomeThing) 執行

public void DoSomeThing(string parameter){//TODO:}

通過Asynchronous.Invoke(DoSomeThing,parameter) 執行

有返回值異步方法調用

public string DoSomeThing(){//TODO:}

通過Asynchronous.Invoke(()=>DoSomeThing())執行

public string DoSomeThing(string parameter){//TODO:}

通過Asynchronous.Invoke(()=>DoSomeThing(parameter))執行,或者也可以傳入參數通過Asynchronous.Invoke(p=>DoSomeThing(p),parameter)

無返回值Foreach

public void Test{int[] parameters = {1,2,3,4,5};Asynchronous.Foreach(parameters,Console.WriteLine);}

有返回值Foreach

public void Test{int[] parameters = {1,2,3,4,5};var operators = Asynchronous.Foreach(parameters,p=> p*2);Asynchrous.WaitAll(operators);Asynchronous.Foreach(operators.Cast<FuncAsync<int,int>>(),  p=> Console.WriteLine(p.Result));}

首先將集合每個值擴大2倍,然后輸出
異步執行完再執行

public void Test{int[] parameters = {1,2,3,4,5};var operators = Asynchronous.Foreach(parameters,p=> p*2);Asynchrous.ContinueWithAsync(operators,Console.WriteLine,"執行完成");}

每次執行完繼續執行
可能有時候我們需要遍歷一個集合,每個元素處理完成后我們需要輸出XX處理完成

public void Test{int[] parameters = {1,2,3,4,5};var operators = Asynchronous.Foreach(parameters,p=> p*2);Asynchronous.Foreach(operators,o=>{  o.ContinueWithAsync(()={    //每個元素執行完時執行    if(o.Exception != null)    {      //之前執行時產生未處理的異常,這里可以捕獲到     }  });});}

可以實現鏈式異步操作

public void Chain(){Asynchronous.Invoke(Console.WriteLine,1).ContinueWithAsync(Console.WriteLine,2).ContinueWithAsync(Console.WriteLine,3)}

這樣會按步驟輸出1,2,3
結束語

以上只是列出了部分重載方法,其他重載方法無非就是加參數,本質實際是一樣的。

希望對大家的學習有所幫助,在這祝大家新年快樂,新的一年大家一起努力。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产日韩精品在线观看| 亚洲一区二区在线播放| 国产亚洲精品一区二区| 国产精品久久久久久久久久久久| 国产精品一二三视频| 国产欧美日韩免费看aⅴ视频| 91精品国产高清自在线| 亚洲一区二区中文字幕| 视频一区视频二区国产精品| 最好看的2019年中文视频| 久久久久久网址| 久久久国产精彩视频美女艺术照福利| 日韩在线观看免费av| 久久在精品线影院精品国产| 欧美xxxx18国产| 亚洲精品国产欧美| 国产一区二区精品丝袜| 国产成人精品国内自产拍免费看| 亚洲va欧美va国产综合剧情| 欧美激情图片区| 欧美制服第一页| 日韩精品视频观看| 精品欧美aⅴ在线网站| 黑人巨大精品欧美一区二区| 日韩精品视频免费在线观看| 日韩欧美在线第一页| 北条麻妃一区二区在线观看| 亚洲精选在线观看| 国产午夜精品理论片a级探花| 亚洲国产精彩中文乱码av在线播放| 成人有码在线视频| 国产精品免费一区| 欧美一级视频在线观看| 日韩欧美成人免费视频| 欧美午夜www高清视频| 91地址最新发布| 九九热视频这里只有精品| 亚洲国产精品推荐| 亚洲最新在线视频| 国产精品av电影| 中文综合在线观看| 欧美国产日韩一区二区三区| 欧美在线播放视频| 国内精品久久久久久中文字幕| 91最新国产视频| 日韩电影在线观看免费| 亚洲一区亚洲二区| 亚洲第一区中文字幕| 日韩免费在线视频| 欧美另类极品videosbest最新版本| 日韩欧美在线播放| 欧美成人亚洲成人日韩成人| 亚洲一区二区在线播放| 91国产高清在线| 国产999精品| 国产精品久久久亚洲| 亚洲xxxx3d| 欧美特黄级在线| 久久精品99国产精品酒店日本| 亚洲另类激情图| 性欧美亚洲xxxx乳在线观看| 日韩精品免费在线播放| 欧美激情中文字幕在线| 欧美国产在线电影| 欧美一区二区影院| 日韩中文字幕在线精品| 在线免费观看羞羞视频一区二区| 欧美夫妻性生活xx| 国产偷亚洲偷欧美偷精品| 成人午夜小视频| 亚洲xxxx视频| 日韩在线中文字幕| 伊人久久综合97精品| 亚洲欧美在线第一页| 日韩中文字幕网站| 精品国产自在精品国产浪潮| 久久久精品2019中文字幕神马| 欧美与欧洲交xxxx免费观看| 欧美日韩福利视频| 91免费看国产| 亚洲综合中文字幕68页| 欧美精品www在线观看| 国产欧美在线视频| 中文字幕精品久久| 操91在线视频| 国产不卡精品视男人的天堂| 久久久免费精品视频| 久久久97精品| 国产欧美一区二区三区四区| 精品久久中文字幕久久av| 一区二区在线视频播放| 国产亚洲免费的视频看| 亚洲香蕉成视频在线观看| 久久九九全国免费精品观看| 国产精品在线看| 欧美限制级电影在线观看| 亚洲福利在线看| 精品夜色国产国偷在线| 国产成人精品视频| 国产欧美日韩丝袜精品一区| 日韩精品视频在线免费观看| 在线视频国产日韩| 狠狠躁夜夜躁人人爽超碰91| 裸体女人亚洲精品一区| 欧美成人午夜激情| 久久人91精品久久久久久不卡| 91精品国产91久久久久久吃药| 北条麻妃一区二区在线观看| 欧美午夜片在线免费观看| 国产精品白嫩美女在线观看| 国产成人免费av电影| 国产精品美女久久久久久免费| 精品久久久久久久久久久久久| 国产精品亚洲自拍| 亚洲国产小视频在线观看| 日韩极品精品视频免费观看| 亚洲欧美在线一区二区| 欧美高清视频免费观看| 最近2019中文免费高清视频观看www99| 亚洲色图50p| 亚洲综合精品一区二区| 国产精品av网站| 久久久久亚洲精品国产| 热久久美女精品天天吊色| 欧美激情视频在线观看| 成人黄色av播放免费| 亚洲国产精品成人va在线观看| 国产精品自产拍在线观看中文| 日韩福利在线播放| 国产日韩精品综合网站| 亚洲第一福利视频| 亚洲网站视频福利| 国产精品香蕉在线观看| 国产做受高潮69| 日韩精品黄色网| 欧美国产高跟鞋裸体秀xxxhd| 欧美乱人伦中文字幕在线| 亚洲三级 欧美三级| 亚洲影院色在线观看免费| 国产精品夜色7777狼人| 丝袜美腿精品国产二区| 亚洲国产精品va在线观看黑人| 久久久精品久久久久| 日本精品免费观看| 国产精品一区二区三| 欧美自拍大量在线观看| 26uuu国产精品视频| 国产成人精品视频在线观看| 日韩精品免费观看| 国内成人精品一区| 91综合免费在线| 国产成人精品一区二区三区| 日本高清久久天堂| 色综合91久久精品中文字幕| 久久精品国产亚洲精品| 国产精品美女免费| 欧美日韩视频免费播放| 欧美黑人一级爽快片淫片高清| 九色91av视频| 欧美性做爰毛片| 国产欧美va欧美va香蕉在线| 亚洲免费伊人电影在线观看av| 成人h猎奇视频网站| 国产精品久久在线观看|