简单实现C#异步操作

2019-12-26 17:28:50王旭
这篇文章主要为大家详细介绍了C#简单实现异步操作的方法,通过BeginInvoke、EndInvoke的方式实现异步编程,感兴趣的小伙伴们可以参考一下  

在.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;
      }
    }