• C#多线程之线程池篇一APM(Asynchronous Programming Model)【在线程池中调用委托】


      APM(Asynchronous Programming Model)是.Net 旧版本中广泛使用的异步编程模型,但在现代编程中,更推荐使用TPL(Task Parallel Library),他是.Net 4.0 之后带来的新特性 TaskAsync。
         static void Main(string[] args)
            {
                int threadId = 0;
    
                RunOnThreadPool poolDelegate = Test;
    
                var t = new Thread(() => Test(out threadId));
                t.Start();
                t.Join();
    
                Console.WriteLine("Thread id: {0}", threadId);
    
                IAsyncResult r = poolDelegate.BeginInvoke(out threadId, Callback, "a delegate asynchronous call");
                r.AsyncWaitHandle.WaitOne();
    
                string result = poolDelegate.EndInvoke(out threadId, r);
    
                Console.WriteLine("线程池工作线程的: {0}", threadId);
                Console.WriteLine(result);
    
                Thread.Sleep(TimeSpan.FromSeconds(2));
                Console.Read();
            }
    
            private delegate string RunOnThreadPool(out int threadId);
    
            private static void Callback(IAsyncResult ar)
            {
                Console.WriteLine("开始回调...");
                Console.WriteLine("State passed to a callbak: {0}", ar.AsyncState);
                Console.WriteLine("是一个线程池线程: {0}", Thread.CurrentThread.IsThreadPoolThread);
                Console.WriteLine("线程池线程ID是: {0}", Thread.CurrentThread.ManagedThreadId);
            }
    
    
            private static string Test(out int threadId)
            {
                Console.WriteLine("开始...");
                Console.WriteLine("是一个线程池线程: {0}", Thread.CurrentThread.IsThreadPoolThread);
                Thread.Sleep(TimeSpan.FromSeconds(2));
                threadId = Thread.CurrentThread.ManagedThreadId;
                return string.Format("线程池工作线程的ID是: {0}", threadId);
            }
     
      当程序运行时,我们使用老办法创建了一个线程,然后启动它,并等待它执行完毕。因为thread的构造方法只接收不带返回值的委托方法,因此,我们给它传递一个lambda表达式,在该表达式中我们调用了“Test”方法。在“Test”方法中,我们使用“Thread.CurrentThread.IsThreadPoolThread”属性值来判断线程是不是来自线程池。我们还使用“CurrentThread.ManagedThreadId”属性值打印出运行当前代码的线程ID。
      然后,我们定义了一个委托,该委托表示的方法的返回值为字符串类型,并且接收一个整型类型的输出参数。
      然后,我们将Test方法赋值给poolDelegate委托,并在第38行代码处,使用委托的“BeginInvoke”方法运行该委托指向的方法(Test)。“BeginInvoke”接收一个回调方法,该方法将在异步操作完成之后被调用。“BeginInvoke”的第三个参数是传递给回调方法的一个用户自定义的状态。通常使用这个状态来分辨一个异步调用。我们使用“IAsyncResult”接口来保存“BeginInvoke”方法的返回值。
      “BeginInvoke”方法立即返回,这允许我们可以在线程池中的工作线程执行的同时,继续执行调用“BeginInvoke”方法的线程中的下一条代码。
      在第40行代码处,我们可以使用“BeginInvoke”方法的返回值以及对“EndInvoke”方法的调用来获得异步操作的结果。
      注意,第39行代码不是必须的,如果我们注释掉这一行代码,程序仍然运行成功,这是因为“EndInvoke”方法会一直等待异步操作完成。调用“EndInvoke”方法的另一个好处是在工作线程中任何未处理的异常都会抛给调用线程。
      如果我们注释掉第44行代码,回调方法“Callback”将不会被执行,这是因为主线程已经结束,所有的后台线程都会被停止。
  • 相关阅读:
    mac OSX 上 brew install hive
    mac osx 系统 brew install hadoop 安装指南
    python在windows平台的pip安装package时的编译问题
    安装scapy遇到的问题
    node中使用domain处理异步异常问题
    web开发中的 emmet 效率提升工具
    未来10年房地产存量与人口需求量分析
    Apple individual program 加入之后的玩法 官方资源
    nginx 反向代理 与 Apache backend的配置联合配置
    ubuntu 休眠之后网络间接失败 can not connect to network after suspend (wake up)
  • 原文地址:https://www.cnblogs.com/gougou1981/p/12381723.html
Copyright © 2020-2023  润新知