首页 > 其他分享 >如何发布符合 .NET 准则的事件

如何发布符合 .NET 准则的事件

时间:2023-07-03 20:32:23浏览次数:27  
标签:EventHandler 自定义 CustomEventArgs 准则 event 事件 符合 NET public

下面的过程演示了如何将遵循标准 .NET 模式的事件添加到类和结构中。 .NET 类库中的所有事件均基于 EventHandler 委托,定义如下:

public delegate void EventHandler(object sender, EventArgs e);

尽管定义的类中的事件可基于任何有效委托类型,甚至是返回值的委托,但一般还是建议使用 EventHandler 使事件基于 .NET 模式,如下例中所示。

名称 EventHandler 可能导致一些混淆,因为它不会实际处理事件。 EventHandler 和泛型 EventHandler<TEventArgs> 均为委托类型。 其签名与委托定义匹配的方法或 Lambda 表达式是事件处理程序,并将在引发事件时调用。

发布基于 EventHandler 模式的事件

  1. (如果无需随事件一起发送自定义数据,请跳过此步骤转到步骤 3a。)将自定义数据的类声明为对发布服务器和订阅者类均可见的范围。 然后添加所需成员以保留自定义事件数据。 在此示例中,将返回一个简单的字符串。
public class CustomEventArgs : EventArgs
{
    public CustomEventArgs(string message)
    {
        Message = message;
    }

    public string Message { get; set; }
}
  1. (如果使用的是泛型版本 EventHandler<TEventArgs>,请跳过此步骤。)声明发布类中的委托。 为其指定以 EventHandler 结尾的名称。 第二个参数指定自定义 EventArgs 类型。
public delegate void CustomEventHandler(object sender, CustomEventArgs args);
  1. 使用下列步骤之一来声明发布类中的事件。
  1. 如果没有任何自定义 EventArgs 类,事件类型将为非泛型 EventHandler 委托。 你无需声明该委托,因为它已在创建 C# 项目时包括的 System 命名空间中声明。 将以下代码添加到发布服务器类。
public event EventHandler RaiseCustomEvent;
  1. 如果使用非泛型版本 EventHandler 并且具有派生自 EventArgs 的自定义类,请声明发布类中的事件,并将步骤 2 中的委托用作类型。
public event CustomEventHandler RaiseCustomEvent;
  1. 如果使用泛型版本,则无需自定义委托。 而是在发布类中,将事件类型指定为 EventHandler<CustomEventArgs>,替换尖括号中自定义类的名称。
public event EventHandler<CustomEventArgs> RaiseCustomEvent;

示例

下例通过使用自定义 EventArgs 类和 EventHandler<TEventArgs> 作为事件类型来演示之前的步骤。

using System;

namespace DotNetEvents
{
    // Define a class to hold custom event info
    public class CustomEventArgs : EventArgs
    {
        public CustomEventArgs(string message)
        {
            Message = message;
        }

        public string Message { get; set; }
    }

    // Class that publishes an event
    class Publisher
    {
        // Declare the event using EventHandler<T>
        public event EventHandler<CustomEventArgs> RaiseCustomEvent;

        public void DoSomething()
        {
            // Write some code that does something useful here
            // then raise the event. You can also raise an event
            // before you execute a block of code.
            OnRaiseCustomEvent(new CustomEventArgs("Event triggered"));
        }

        // Wrap event invocations inside a protected virtual method
        // to allow derived classes to override the event invocation behavior
        protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
        {
            // Make a temporary copy of the event to avoid possibility of
            // a race condition if the last subscriber unsubscribes
            // immediately after the null check and before the event is raised.
            EventHandler<CustomEventArgs> raiseEvent = RaiseCustomEvent;

            // Event will be null if there are no subscribers
            if (raiseEvent != null)
            {
                // Format the string to send inside the CustomEventArgs parameter
                e.Message += $" at {DateTime.Now}";

                // Call to raise the event.
                raiseEvent(this, e);
            }
        }
    }

    //Class that subscribes to an event
    class Subscriber
    {
        private readonly string _id;

        public Subscriber(string id, Publisher pub)
        {
            _id = id;

            // Subscribe to the event
            pub.RaiseCustomEvent += HandleCustomEvent;
        }

        // Define what actions to take when the event is raised.
        void HandleCustomEvent(object sender, CustomEventArgs e)
        {
            Console.WriteLine($"{_id} received this message: {e.Message}");
        }
    }

    class Program
    {
        static void Main()
        {
            var pub = new Publisher();
            var sub1 = new Subscriber("sub1", pub);
            var sub2 = new Subscriber("sub2", pub);

            // Call the method that raises the event.
            pub.DoSomething();

            // Keep the console window open
            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
        }
    }
}


作者:古道轻风


标签:EventHandler,自定义,CustomEventArgs,准则,event,事件,符合,NET,public
From: https://blog.51cto.com/chunyangi/6615234

相关文章

  • 记一次.net加密神器 Eazfuscator.NET 2023.2 最新版 使用尝试
    合集-.net代码混淆加密产权保护(2) 1.记一次.net加密神器Eazfuscator.NET2023.2最新版使用尝试06-272.将SmartAssembly与单文件可执行文件一起使用(.NETCore6)06-27收起 很多人看到这个Eazfuscator.NET还不知是什么东东。。。首先介绍下。什么是Eazfu......
  • 利用Lucene.net搜索引擎进行多条件搜索的做法
    利用Lucene.net搜索引擎进行多条件搜索的做法1联合两个索引查询,已解决:IndexSearcher[]searchers=newIndexSearcher[2];  searchers[0]=newIndexSearcher(m_indexpath);searchers[1]=newIndexSearcher(m_outindexpath);MultiSearchermultiSearcher=newMult......
  • Profinet转EtherNet/IP网关连接AB PLC的应用案例
     西门子S7-1500PLC(profinet)与ABPLC以太网通讯(EtherNet/IP)。本文主要介绍捷米特JM-EIP-PN的Profinet转EtherNet/IP网关,连接西门子S7-1500PLC与ABPLC通讯的配置过程,供大家参考。 1,新建工程:运行RSLogix5000程序,选择菜单File->New,弹出对话框:2,在“Type”中选择控......
  • Spike timing reshapes robustness against attacks in spiking neural networks
    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布!同大组工作......
  • 避坑:.NET内存泄露的几种情况
    内存“泄露”是开发中常见的问题之一,它会导致应用程序占用越来越多的内存资源,最终可能导致系统性能下降甚至崩溃。软件开发者需要了解在程序中出现内存泄露的情况,以避免软件出现该的问题。什么是内存“泄露”?内存泄露是申请了内存空间的变量一直在占用,无法释放。比如申请了一块......
  • 【.Net/C#之ChatGPT开发系列】四、ChatGPT多KEY动态轮询,自动删除无效KEY
    ChatGPT是一种基于Token数量计费的语言模型,它可以生成高质量的文本。然而,每个新账号只有一个有限的初始配额,用完后就需要付费才能继续使用。为此,我们可能存在使用多KEY的情况,并在每个KEY达到额度上限后,自动将其删除。那么,我们应该如何实现这个功能呢?还请大家扫个小关。......
  • ASP.NET Core SignalR 入门
    本章将和大家分享使用SignalR生成实时应用的基础知识。通过本文您将学习如何:使用ASP.NETCoreSignalR+MVC+Vue2.x+require最终创建一个正常运行的简易聊天应用。废话不多说,我们直接来看一个Demo,Demo的目录结构如下所示:本Demo的Web项目为ASP.NETCoreWeb应用程序(目......
  • .net core读取配置文件
    先添加这两个开发包: 这是配置文件; {"Logging":{"LogLevel":{"Default":"Information","Microsoft.AspNetCore":"Warning"}},"AllowedHosts":"*","......
  • dotnet-微服务学习-dotnet集成SkyWaking链路追踪
    关于链路追踪的原来我们单独开一篇文章讲解这里我们来讲解SkyWaking的安装和集成 首先进入SkyWaking官网下载最新的包网址如下: https://skywalking.apache.org/downloads/ 1.1windows安装下载后Winwos直接运行双击bin目录下的startup.bat即可 注意 SkyWalk......
  • CANopen转ProfiNet网关在大跨径门机起重设备同步纠偏控制应用案例
     大型门机起重设备纠偏控制系统采用CanOpen通讯协议,而PLC使用的是ProfiNet协议,看似不兼容的两种协议如何实现互通?今天我们来看一下这个案例。通过捷米特JM-COP-PN设置纠偏系统的参数,同时采集门机左右双轨的轮子多点同步控制,速度、位置等信息。在经过简单的配置后,用户可以很轻......