zoukankan      html  css  js  c++  java
  • C# 异步编程学习(一)

    异步 编程 可在 等待 某个 任务 完成时, 避免 线程 的 占用, 但要 想 正确地 实现 编程, 仍然 十分 伤脑筋。

    . 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)
            {
                et = 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;
                }
    
            } 
        }
    View Code

    调用代码:

     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

  • 相关阅读:
    关于hibernate的缓存使用(转)
    Webservice 实践
    三大电商注册登录表单分析
    网上好文搜集
    git简介
    Python程序中的进程操作--—--开启多进程
    进程的创建和结束
    同步异步阻塞和非阻塞
    进程的并行和并发
    进程调度
  • 原文地址:https://www.cnblogs.com/zhlziliaoku/p/9217170.html
Copyright © 2011-2022 走看看