在上篇文章提到了进行异步调用的时候,我们可以手动指定超时时间和阻塞时间,然后再调用委托的EndInvoke()方法得到我们要的结果。然而,如果我们想在进行异步调用的时候进行很好的管理得话,那使用完成回调方法将是一个不错的选择。

一:回调方法的签名和工作机制
        1.回调方法必须要符合以下签名:
        <修饰符>void <方法名>(IAsynResult asynResult);回调的方法的名称的统一规范是在名称前面加On ,如:OnAsynCallBack();(注:命名事件和委托等类型时候同样有类似的惯例),
        2.工作机制:
        .Net使用从线程池中得到的线程来执行通过BeginInvoke()分配的方法,当异步方法执行完成时,工作线程调用回调方法而不只直接回到线程池中,要实现回调方法,我们必须在使用beginInvoke()方法的时候指定一个参数为IAsynResult类型的方法,因为在AsynResult是一个.Net中已经定义好的委托,我们要使用回调方法的话,就必须符合他的要求:他的定义如下,public delegate void AsynCallBack(IAsynResult asynResult);

示例:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Messaging;
using System.Diagnostics;

namespace Asyn
{
    public delegate int BinaryOperation(int argument1,int argument2);

    class Program
    {
        static void Main(string[] args)
        {
            CalCulatorClent.AsynAdd();
        }
    }

    public class Calculator
    {
        public int Add(int argument1, int argument2)
        {
            return argument1 + argument2;
        }

        public int Sub(int argument1, int argument2)
        {
            return argument1 - argument2;
        }
    
    }

    public class CalCulatorClent
    {
        public static void AsynAdd()
        {

            Calculator calculator = new Calculator();
            BinaryOperation oppDel = calculator.Add;
            oppDel.BeginInvoke(2, 3, OnMethodCompletion, null);

        }
        private static void OnMethodCompletion(IAsyncResult asynResult)
        {
            int result = 0;

            AsyncResult resultObj=(AsyncResult)asynResult;
            System.Diagnostics.Debug.Assert(resultObj.EndInvokeCalled==false);//如果没调用,则输出

            BinaryOperation oppDel = (BinaryOperation)resultObj.AsyncDelegate;//获取原来的委托
            result = oppDel.EndInvoke(asynResult);
            Console.WriteLine("Operation returned "+result.ToString());
            Console.Read();
        }
    }

}

注:上面的示例有一个要值得注意,就是获取原始委托的方法,获取原始委托用的是System.Runtime.Remoting.Messaging;
名字空间下的AsynResult,它继承自IAsynResult,通过它的AsyncDelegate属性,我们就得到了对应BeginInvoke()方法的委托,同时还可以利用它的属性EndInvokeCalled来确定EndInvoke()是否被调用。

二:回调方法与线程安全
   因为回调方法是在线程池中的一个线程中运行的,所以关于线程安全方面也要考虑。特别是对于一些共享资源如数据库连接对象等就要考虑到并发带来的问题,我们可以加同步锁(用lock关键字)来访问这些资源。

三:传递状态信息

BeginInvoke()的最后一个参数,object asyncState,作为.NET中的作为泛用容器被提供的状态对象。处理方法完成的部分可以访问类似于IAsyncResult中AsyncState属性的容器对象。虽然也可以在其他.NET异步调用编程模型(阻塞,等待或轮询)中使用状态对象,但与完成方法一起使用时最有用处。原因很简单:在其他编程模型中,不仅必须管理IAsyncResult对象,而且还要管理一个额外的增加管理责任的容器对象。当通过完成回调使用容器对象时,仅需要给回调方法传入一个额外的参数,而且已通过.NET在方法签名中预订了。

转载于:https://www.cnblogs.com/hanchan/archive/2007/09/18/897094.html

C# 异步调用中使用回调方法相关推荐

  1. 使用ASP.NET AJAX异步调用Web Service和页面中的类方法(2):处理异步调用中的异常...

    本文来自<ASP.NET AJAX程序设计 第II卷:客户端Microsoft AJAX Library相关>的第三章<异步调用Web Service和页面中的类方法>,请同时 ...

  2. odciexttableopen 调用出错 error open log_如何在 Spring 异步调用中传递上下文

    什么是异步调用? 异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行.异步调用指,在程序在执行时,无 ...

  3. delphi 异步 调用 带参数_如何在 Spring 异步调用中传递上下文

    什么是异步调用? 异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行.异步调用指,在程序在执行时,无 ...

  4. ruby中的回调方法和钩子方法

    在ruby中,当某些特定的事件发生时,将调用回调方法和钩子方法.事件有如下几种: 调用一个不存在的对象方法 类混含一个模块 定义类的子类 给类添加一个实例方法 给对象添加一个单例方法 引用一个不存在的 ...

  5. .NET MVC异步调用中的Session问题

    需要异步处理一个输入问题. 以下均代码适用 MVC4 controller 代码如下: public class TestController : AsyncController {          ...

  6. 巧用Delegate在Silverlight多个页面、控件中传递回调方法

    在论坛中看到经常有人碰到如何在SilverLight多个页面或者控件中传替参数或者值的问题,今天抽空通过Delegate机制实现回调实例方法重设动画参数的DEMO,分享给大家.最终结果如图: 在论坛中 ...

  7. C语言中的函数指针、函数的直接/间接调用、C# 委托(自定义委托、内置泛型委托、委托的实例化、委托的一般使用(模板方法、回调方法)、泛型委托、多播委托、同步/异步使用委托)

    文章目录 C语言中的函数指针 函数的直接调用与间接调用 Java中没有与委托对应的功能实体 C# 委托 C# 自定义委托类型 C# 内置泛型委托类型 委托的实例化 委托也支持泛型的使用 委托的一般使用 ...

  8. JavaScript 循环中调用异步函数的三种方法,及为什么 forEach 无法工作的分析

    JavaScript 循环中调用异步函数的三种方法,及为什么 forEach 无法工作的分析 业务分析 初版的问题 解决方案 传统的 for 循环 不使用 for 循环的解决方案 分析 forEach ...

  9. 17委托异步调用方法

    抽象出一个炒菜的类. 1: //炒菜 2: public class Cooking 3: { 4: public string Cook(string food1, string food2) 5: ...

  10. C#中的异步调用剖析

    我上次写创建线程的时候就想写一篇深入异步调用的笔记,但是由于当时对windows的进程与线程的概念不太清楚,没敢写,今天我仔细的分析并调试了一下C#中的异步调用的四种方法.把学习笔记分享出来. 假如要 ...

最新文章

  1. 企业管理:高层不狠,中层不坏,累死三军
  2. 当法律纽带变成“机器红线”,能让自动驾驶汽车更安全吗?
  3. 符合.net准则的事件
  4. ffmpeg的编译大全
  5. 一份【软件工程】的学习指南已到达,请注意查收!!
  6. Oracle Dba手记(读书笔记)
  7. 关于 django 的时区设置与MySQL 时间相差8小时
  8. ssm指的是什么_什么是RESTful?RESTfule风格又是啥?
  9. Librtmp的交叉编译详解
  10. 2022年全球市场巧克力行业发展前景分析及市场需求调研报告
  11. 《企业财务报表分析》学习笔记
  12. 查看已连接的WiFi密码
  13. 怎么获取公众号二维码?
  14. html ppt在线浏览,怎么在网页中在线浏览PPT文档?
  15. xp2 server application error 错误解决
  16. 回顾Vue2---②
  17. 一流的产品,繁荣的生态,优质的服务,领先的市场,强大的组织 —2022新年寄语
  18. 在python中浮点数怎样转整数_python 浮点数 转 整数python函数每日一讲 - all()
  19. windows平台下载并编译webrtc代码(代理)2021.8.11
  20. ✨数织游戏✨:Python 制作的成本一毛钱却诚意满满的小礼物!!

热门文章

  1. Mysql rpm包安装
  2. 0302-l2tp_***(ruijie)通用版
  3. 仿Android 5.0 侧滑菜单按钮动画 以及侧滑菜单联动
  4. 给定一个字符串,求第一个不重复的字符
  5. [2018.10.10 T3] 三米诺
  6. http抓包实践--(五)-常用的操作
  7. ES6、7学习笔记(尚硅谷)-8-三点运算符
  8. vlan为什么能隔离广播域_【思唯网络学院】VLAN是二层技术还是三层技术?
  9. 获取服务器响应失效,从Web服务器获取响应时出现问题
  10. 系统辨识理论及应用_液压系统故障智能诊断方法(2)