c#防止事件重复注册,调用后就移除注册,跨程序集的事件订阅

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleAppNET7
{
    public class UploadFile
    {

        static UploadFile()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        Delegate[] delegates = ImgCalcAmount.GetInvocationList();
                        Console.Out.WriteLine("注册事件数" + delegates.Length);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("事件数量为0,获取异常," + ex.Message);
                        break;
                    }

                    Thread.Sleep(100);
                }
            });
        }
 
        /// <summary>
        /// 小图片数量,通知
        /// </summary>
        public static event EventHandler<string> ImgCalcAmount;

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="html"></param>
        /// <param name="articleId"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public static async Task<Dictionary<string, string>> UploadFileWork(string html, string articleId, string user)
        {
            Dictionary<string, string> dict = new Dictionary<string, string>();
 
            await Task.Delay(100);
 
            //计算小图数量
            int count = int.Parse(articleId.Last().ToString()) + 1;
            for (int i = 0; i < count; i++)
            {
                if (count % 2 == 0)
                {
                    await Task.Delay(3000);
                }
                if (count % 3 == 0)
                {
                    await Task.Delay(1000);
                }

                //找到一张小图片,通知调用方,小图数量 +1
                ImgCalcAmount?.Invoke(1, articleId);
            }
            return dict;
        }

    }
}
csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleAppNET7
{
    internal class BusinessTest
    {

        public static async Task PublishArticle(string articleId)
        {
            short imgAmount = 0; /* 小图数量计数 */
            EventHandler<string> action = (o, e) =>
            {
                if (e == articleId)
                {
                    imgAmount = (short)(imgAmount + 1);
                }
            }; 
            UploadFile.ImgCalcAmount += action;

            //上传文件处理
            await UploadFile.UploadFileWork("文章内容html", articleId, "李斯");

            //移除注册
            UploadFile.ImgCalcAmount -= action;

            //上传完成;     
            Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")},文章{articleId},小图片数{imgAmount}");
             
        }

    }
}
csharp 复制代码
// See https://aka.ms/new-console-template for more information
using ClassLibrary.Tool;
using ConsoleAppNET7;

Console.WriteLine("Hello, World!");

//
for (int i = 0; i < 10; i++) {
    BusinessTest.PublishArticle("1000"+i);
}

Task.Delay(2000).Wait();

for (int i = 0; i < 10; i++)
{
    BusinessTest.PublishArticle("2000" + i);
}
 
Console.WriteLine("程序结束----");
Console.ReadKey();
相关推荐
小金子会发光4 分钟前
C# WinForms 基于 Socket 手搓 Modbus TCP 调试助手(支持 01/02/03/04/05/06/0F/10)
c#·socket·plc·modbus tcp·工业通信
啊哈一半醒14 分钟前
Go 语言 Context 全方位详解:原理、实战与避坑
开发语言·后端·golang
铅笔侠_小龙虾17 分钟前
rust 学习(9):结构体
开发语言·学习·rust
此生决int27 分钟前
深入理解C++系列(11)——stack、queue和priority_queue
开发语言·c++
周杰伦fans31 分钟前
数列极限的定义
java·开发语言
2601_963869952 小时前
【计算机毕业设计】基于Java的潮牌购物网站系统的设计与实现
java·开发语言·课程设计
名字还没想好☜2 小时前
Go 的 io.Reader/Writer 组合实战:io.Copy、TeeReader、MultiWriter 优雅处理数据流
开发语言·后端·golang·go·iphone
郝学胜-神的一滴2 小时前
Qt 高级编程 042:进度条从入门到自定义美化
开发语言·c++·qt·软件开发·用户界面
鸿芯微控科技3 小时前
压电纳米定位分辨率怎么测?噪声、带宽、最小可检测位移与Python分析
开发语言·python·噪声分析·压电执行器·纳米定位·位移测量
会编程的土豆3 小时前
从「锁」到「时间」:后端里几个容易混的概念
java·开发语言·数据库·goland