zoukankan      html  css  js  c++  java
  • C#中运用事件实现异步调用

    问题引出:

    winform程序中的耗时操作,一般不能在UI线程中执行,需要另开线程。往往我们需要在耗时操作结束后将结果显示在UI上。

    以下是Mainform.cs中调用耗时操作的一段代码:

    1     Job j = new Job();
    2     j.runJob();


    这里耗时操作被封装在类Job中,调用 j.runJob() 开始耗时操作。其中runJob中封装了开启新线程执行任务的代码。

    Job运行完后需要返回一个结果并显示在UI上。

    显而易见的方法是,在Job中实例化一个Mainform对象,然后直接在Job中对UI进行修改。这种方法极其不提倡,极大的增加了类之间的耦合性。

    可以想到的一种合理的方法,Job类完成了耗时任务之后给调用它的类发送“消息”,”消息“中还包括了应该显示的结果。Job方还应该做到:只管发送”消息“,而不管发送给谁。这样就算更换了调用方,Job类的代码也不需要进行修改。这样的”消息“在C#中即为”事件“。


    方法步骤:

    1.在Job类(需要调用其他类中方法的类)中声明这两个变量:

    1         public delegate void FinishHandler(int param);   //声明委托
    2         public event FinishHandler FinishEvent;          //声明事件


     委托的变量名可随意命名,括号中定义了要传递参数的类型和个数,这里需要传递一个int变量。

     第二行事件的类型要于委托的名称一样。

    2.在Job类(需要调用其他类中方法的类)中合适的地方调用事件:

    1     FinishEvent(score);


    合适的地方一般来说就是耗时操作结束,需要返回结果时。

     括号内参数形式与个数要与第一步中定义的一致。

    3.将事件发生时需要执行的方法注册到事件中

    1     Job j = new Job();    
    2     j.FinishEvent += updateData;
    3     j.runJob();


    当然,updateData的参数形式和个数也和第一步时一样。

    分析总结:

    梳理一下运行程序时发生了什么。

    实际运行时,首先运行的是第3步中的三行代码。

    第二行表示updateData方法会被j对象中的FinishEvent事件触发。


    第三行开始运行耗时任务,Job类在执行到任务结束准备返回数据时,来到了第二步中的那行代码,此时,会触发所有注册了该事件的方法开始执行。
    这样从MainForm的角度看,实现了异步调用,耗时任务的结果通过另一个函数读取。

    从Job类的角度看,调用了另一个类中的方法。

    更多应用待之后编程实践中发现。

  • 相关阅读:
    (6)在树莓派上截屏的方法
    (7)树莓派读物USB摄像头
    (4)给树莓派安装中文输入法Fcitx及Google拼音输入法
    (3)使用Android手机作为树莓派的屏幕
    (2)在树莓派安装运行在Python3上的OpenCV
    相机靶面尺寸和视场角换算
    STM32F103C8T6在Arduino IDE里编程
    项目(二) esp32-cam 网页图像人脸
    开发(一) ardunio环境配置 针对esp32-cam 更多例程
    [转] Compile、Make和Build的区别
  • 原文地址:https://www.cnblogs.com/in4ight/p/5790181.html
Copyright © 2011-2022 走看看