012.使用传统.NET事件进行通知操作

news2025/1/20 3:40:46

Rx的目标是协调和编排来自各种来源的基于事件的异步计算,如社交网络、传感器、UI事件等。例如,建筑物周围的安全摄像头,以及当有人可能在建筑物附近时触发的运动传感器,会向我们发送最近摄像头的照片。Rx还可以统计包含选举候选人姓名的推文,以估计候选人的受欢迎程度。这是通过以异步方式调用外部web服务来完成的。对于这些场景和其他类似的场景,编排往往会导致复杂的程序,正如你所看到的,Rx肯定会减轻这种努力。

在本章中,您将查看一个示例,了解使用和不使用Rx对应用程序的结构、可读性以及扩展和发展的容易程度有何影响。想象一下,你收到了Stocks R Us公司著名首席技术官Penny先生的一封信。Stocks R Us是一家股票交易公司,为客户提供资金投资和从收益中选择利息的建议。这就是为什么对公司来说,对股票市场的变化做出快速反应很重要。最近,Stocks R Us发现,它可以通过使用一个系统来节省资金,该系统可以为经历了剧烈变化的股票提供警报,正如Penny先生所说。Penny先生对剧烈变化的定义是超过10%的价格变化。当这些变化发生时,Stocks R Us希望尽快知道,以便通过出售或购买股票做出反应。

Penny先生来找你是因为他知道他可以指望你快速提交高质量的申请。您的工作(也是本章的目标)是创建一个应用程序,向用户通知经历剧烈变化的股票。当股票价值在两次读数之间增加或减少一定阈值(在这种情况下为10%)时,就会发生剧烈变化。当这种情况发生时,您希望通过向用户的手机发送推送通知或在应用程序的屏幕上显示警报(例如,显示红色闪烁条)来通知用户。

在本章的第一部分中,您将探索使用传统方法创建应用程序时通常会发生的步骤.NET事件方法。然后,我们将分析解决方案并讨论其弱点。

本章的第二部分将Rx介绍到您的应用程序中。您将首先将库添加到项目中,然后逐步以Rx样式制作Stocks R Us的应用程序。

股票信息来自股票交易来源,许多服务都提供这些信息。每个都有自己的API和数据格式,其中一些来源是免费的,比如雅虎财经(http://finance.yahoo.com)以及谷歌金融www.Google.com/Finance)。对于您的应用程序,最重要的属性是股票的报价符号和价格。股票的报价符号是一系列唯一标识交易股票或股票的字符(例如,MSFT是Microsoft股票符号)。

图2.1中的流程图描述了应用程序的逻辑流程。
在这里插入图片描述
图2.1库存回收单元应用程序逻辑的流程图。我们通知用户发生剧烈变化——价格变化超过10%。

对于应用程序接收到的每一条股票信息,它都会将股票的价差计算为新价格和先前价格之间的变化率。假设你收到一个更新,MSFT的价格从50美元变为40美元,变化了20%。这被认为是一个剧烈的更改,并导致在应用程序中显示警报。

在现实生活中,股票点的到达速度是可变的。目前,为了避免混淆你,你可以假设股票点以恒定的速度到达;你稍后会处理时间方面的问题。

为了保持股票信息的来源摘要,它通过类StockTicker公开。该类只公开一个关于StockTick的事件,每当有关于股票的新信息可用时就会引发该事件。

清单2.1 StockTicker类

class StockTicker
{
 public event EventHandler<StockTick> StockTick; 
}

StockTick类保存有关股票的信息,例如其报价符号和价格。

清单2.2 StockTick类

class StockTick
{
 public string QuoteSymbol { get; set; }
 public decimal Price { get; set; }
 //other properties
}

你通常会看到传统的.NET事件。当需要向应用程序提供通知时.NET是将数据传递到应用程序的标准方式。要处理股票报价,您将创建一个StockMonitor类,该类将通过+=运算符连接到StockTick事件来侦听股票变化。

清单2.3 StockMonitor类

class StockMonitor
{ 
 public StockMonitor(StockTicker ticker)
 {
 ticker.StockTick += OnStockTick; //每次引发事件时都会调用OnStockTick方法。
 }
...
 //rest of the code
}

该示例的核心是OnStockTick方法。在这里,如果你已经有了以前的股票报价,你将检查每个股票报价,以便将新价格与旧价格进行比较。为此,您需要一个容器来保存有关以前股票点的所有信息。因为每个刻度都包含QuoteSymbol,所以使用字典来保存这些信息是有意义的,并将QuoteSymol作为关键字。要保存有关先前tick的信息,请定义一个名为StockInfo的新类(清单2.4),然后可以在StockMonitor类中声明字典成员(清单2.5)。

清单2.4 StockInfo类

class StockInfo
{
 public StockInfo(string symbol, decimal price)
 {
 Symbol = symbol;
 PrevPrice = price;
 }
 public string Symbol { get; set; }
 public decimal PrevPrice { get; set; }
}

每次使用新股票点调用OnStockTick时,应用程序都需要检查旧价格是否已保存到词典中。如果您要查找的键存在于字典中,则使用TryGetValue方法返回true,然后使用存储在该键下的值设置out参数。

清单2.5检查股票是否存在的OnStockTick事件处理程序

Dictionary<string,StockInfo> _stockInfos=new Dictionary<string, StockInfo>();
void OnStockTick(object sender, StockTick stockTick)
{
 StockInfo stockInfo ;
 var quoteSymbol = stockTick.QuoteSymbol;
 var stockInfoExists = _stockInfos.TryGetValue(quoteSymbol, out stockInfo);
...
}

如果股票信息存在,您可以检查股票的当前和以前的价格,如以下列表所示,以查看变化是否大于定义剧烈变化的阈值。

清单2.6处理剧烈价格变化的OnStockTick事件处理程序

const decimal maxChangeRatio = 0.1m;
...
var quoteSymbol = stockTick.QuoteSymbol;
var stockInfoExists = _stockInfos.TryGetValue(quoteSymbol, out stockInfo);
if (stockInfoExists)
{
	 //stockInfo变量保存有关股票的信息;因为stockInfoExists是true,所以您可以确定stockInfo不是null。
	 var priceDiff = stockTick.Price-stockInfo.PrevPrice; 
	 //变化的百分比
	 var changeRatio = Math.Abs(priceDiff/stockInfo.PrevPrice); 
	 if (changeRatio > maxChangeRatio)
	 {
		 //Do something with the stock – notify users or display on screen
		 Console.WriteLine("Stock:{0} has changed with {1} ratio, 
		 Old Price:{2} New Price:{3}", 
		 quoteSymbol,
		 changeRatio,
		 stockInfo.PrevPrice,
		 stockTick.Price);
	 }
	 //为下一个事件保存价格。
	 _stockInfos[quoteSymbol].PrevPrice = stockTick.Price; 
}

如果库存信息不在字典中(因为这是你第一次打勾),你需要用

_stockInfos[quoteSymbol]=new StockInfo(quoteSymbol,stockTick.Price);

当不再需要更新时(例如,当用户决定停止接收通知或关闭页面时),您需要使用-=运算符从事件中注销。但是你应该在哪里做呢?一种选择是在StockMonitor类中创建一个方法,当您想要停止时可以调用该方法。但幸运的是。NET通过实现IDisposable接口提供了一种处理这种类型的“清理”的机制,该接口包括用于释放资源的单个方法Dispose。这是它在StockMonitor中的样子:

public void Dispose()
{
 _ticker.StockTick -= OnStockTick; 
 _stockInfos.Clear();
}

完整的代码如清单2.7所示。我在以下系列中运行了它:

Symbol: “MSFT” Price: 100
Symbol: “INTC” Price: 150
Symbol: “MSFT” Price: 170
Symbol: “MSFT” Price: 195

我得到了以下结果:

Stock:MSFT has changed with 0.7 ratio, Old Price:100 New Price:170
Stock:MSFT has changed with 0.15 ratio, Old Price:170 New Price:195.5

清单2.7 StockMonitor完整代码

class StockMonitor : IDisposable
    {
        private readonly StockTicker _ticker;

        Dictionary<string, StockInfo> _stockInfos =
        new Dictionary<string, StockInfo>();
        public StockMonitor(StockTicker ticker)
        {
            _ticker = ticker;
            ticker.StockTick += OnStockTick;
        }

        void OnStockTick(object sender, StockTick stockTick)
        {
            const decimal maxChangeRatio = 0.1m;
            StockInfo stockInfo;
            var quoteSymbol = stockTick.QuoteSymbol;
            var stockInfoExists =
            _stockInfos.TryGetValue(quoteSymbol, out stockInfo);
            if (stockInfoExists)
            {
                var priceDiff = stockTick.Price - stockInfo.PrevPrice;
                var changeRatio = Math.Abs(priceDiff / stockInfo.PrevPrice);
                if (changeRatio > maxChangeRatio)
                {
                    Debug.WriteLine("Stock:{0} has changed with {1} ratio OldPrice:{ 2}newPrice: { 3}", quoteSymbol,changeRatio, stockInfo.PrevPrice, stockTick.Price);
                }
                _stockInfos[quoteSymbol].PrevPrice = stockTick.Price;
            }
            else
            {
                _stockInfos[quoteSymbol] =
                new StockInfo(quoteSymbol, stockTick.Price);
            }
        }
        public void Dispose()
        {
            _ticker.StockTick -= OnStockTick;
            _stockInfos.Clear();
        }
    }

Penny先生很满意,Stock R Us的工作人员正在使用该应用程序,其效果已经显示在他们的报告中。该应用程序接收股票更新,可以计算新旧价格之间的差额比率,并向用户发送警报。

就像生活中的一切一样,变化是不可避免的,Stocks R Us决定改变其股票信息来源。幸运的是,您使用StockTicker类抽象了源代码,因此StockTicker是唯一需要更改的类。

源代码更改后,您开始收到有关崩溃和其他错误的投诉,如丢失警报或不必要的警报。因此,您开始研究这个问题,并发现它与并发性有关。

——未完待续

——重庆教主(QQ23611316) 2024.05.16

——WPF中文网 wpfsoft.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1682121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关爱内向儿童:理解与支持助力成长

引言 每个孩子都是独特的&#xff0c;有些孩子天生性格外向&#xff0c;善于表达&#xff0c;而有些孩子则比较内向&#xff0c;喜欢独处。内向并不是缺点&#xff0c;而是一种性格特质。然而&#xff0c;内向的孩子在社交和学习过程中可能会面临一些挑战。本文将探讨内向儿童…

光伏运维系统在光伏电站的应用

摘要&#xff1a;全球化经济社会的快速发展,加快了传统能源的消耗,导致能源日益短缺,与此同时还带来了严重的环境污染。因此,利用没有环境污染的太阳能进行光伏发电获得了社会的普遍关注。本文根据传统式光伏电站行业的发展背景及其监控系统的技术设备,给出了现代化光伏电站数据…

Python 机器学习 基础 之 监督学习 【分类器的不确定度估计】 的简单说明

Python 机器学习 基础 之 监督学习 【分类器的不确定度估计】 的简单说明 目录 Python 机器学习 基础 之 监督学习 【分类器的不确定度估计】 的简单说明 一、简单介绍 二、监督学习 算法 说明前的 数据集 说明 三、监督学习 之 分类器的不确定度估计 1、决策函数 2、预测…

20232831 袁思承 2023-2024-2 《网络攻防实践》第10次作业

目录 20232831 袁思承 2023-2024-2 《网络攻防实践》第10次作业1.实验内容2.实验过程&#xff08;1&#xff09;SEED SQL注入攻击与防御实验①熟悉SQL语句②对SELECT语句的SQL注入攻击③对UPDATE语句的SQL注入攻击④SQL对抗 &#xff08;2&#xff09;SEED XSS跨站脚本攻击实验…

github新手用法

目录 1&#xff0c;github账号注册2&#xff0c;github登录3&#xff0c;新建一个仓库4&#xff0c;往仓库里面写入东西或者上传东西5&#xff0c; 下载Git软件并安装6 &#xff0c;获取ssh密钥7&#xff0c; 绑定ssh密钥8&#xff0c; 测试本地和github是否联通9&#xff0c;从…

防火请技术基础篇:令牌桶机制的剖析与应用

防火墙中的令牌桶机制&#xff1a;深度剖析与应用 在现代网络通信中&#xff0c;防火墙技术发挥着至关重要的作用&#xff0c;它不仅能够实现网络安全防御&#xff0c;还能通过诸如令牌桶算法等机制来有效管理网络流量&#xff0c;保证网络服务的质量。本文将全面深入地探讨防…

Linux(十) 线程,线程控制

目录 一、认识线程 1.1 线程是什么 1.2 为啥要有线程 并行与并发 为什么要有线程(线程的优点) 为什么线程的切换成本更低 1.3 线程的缺点 1.4 线程和进程的区别 二、线程控制 2.1 线程创建 进程ID和线程ID 2.2 线程终止 2.3 线程等待 2.4 线程分离 三、注意 一、…

医院污水一体化处理设备有哪些

医院污水一体化处理设备通常包括以下几个主要组件&#xff1a; 预处理单元&#xff1a;用于去除污水中的固体悬浮物、颗粒物、油脂等&#xff0c;常见的预处理单元包括格栅、沉砂池、油水分离器等。生物处理单元&#xff1a;用于降解有机物质和去除氮、磷等营养物质。常见的生物…

教程:在 Apifox 中将消息通知集成到钉钉、飞书等应用

Apifox 支持将「消息通知」集成到第三方应用平台&#xff0c;包括企业微信、钉钉、飞书、Webhook 和 Jenkins。具体可在项目的【项目设置 -> 通知设置 -> 外部通知】里新建一个通知事件&#xff0c;然后在弹出的界面中配置即可。 在配置界面可以选择需要的触发事件&#…

机器学习-SVM预测

本文使用机器学习SVM对数据进行预测。仅供参考 1、数据 1.1 训练数据集&#xff1a; medol.xlsx文件示例 otv3015-1.9153622093018-1.9634097763021-1.7620284083024-1.789477583 1.2 预测数据集 test.xlsx文件示例 ot35163519 2、模型训练 train.py import pandas as …

国内常用的项目管理软件有哪些?六大企业级项目管理软件大盘点

一、 奥博思 PowerProject 项目管理软件 官方网址&#xff1a;http://www.powerproject.com.cn 北京奥博思软件技术有限公司自成立以来&#xff0c;一直专注于企业级项目管理软件的开发及解决方案&#xff0c;致力于为各类企业&#xff08;制造业、IT交付、金融、汽车及汽车零…

【工具】macOS、window11访问limux共享目录/共享磁盘,samba服务安装使用

一、samba服务安装 Samba是一个免费的开源软件实现&#xff0c;使得非Windows操作系统能够与Windows系统进行文件和打印服务共享。它实现了SMB/CIFS协议&#xff0c;并且能够在Linux、Unix、BSD等多种系统上运行。 安装 samba&#xff1a; sudo yum install samba配置 samba…

通过阿里云的PAI基于开源LLM搭建RAG检索增强对话系统

5月9日参加阿里云AI云峰会活动&#xff0c;学习了下如何借助阿里云的PAI服务进行搭建RAG检索增加对话系统。 前提&#xff1a; 为了方便省钱&#xff0c;建议先通过免费的优惠圈&#xff0c;这样就可以先不花钱学习一下啦。开始实验之前&#xff0c;请务必打开 阿里云免费试用…

VUE 滚动到指定区域scrollIntoView

背景&#xff1a;当前 VUE 页面数据量很大&#xff0c;右侧出现滚动条, 进入该页面&#xff0c;页面定位到指定区域&#xff1b; 项目要求&#xff1a; 进入页面&#xff0c;定位到指定行&#xff08;红色标记&#xff09; 直接看效果&#xff1a; 代码demo&#xff1a; <…

堆的概念及结构

目录 堆的性质&#xff1a; 堆的实现 堆向下调整算法 堆的创建 堆的插入 堆的删除 堆的应用 堆排序 对比冒泡的优势&#xff1a; 代码 头文件 源文件 如果有一个关键码的集合K { &#xff0c; &#xff0c; &#xff0c;…&#xff0c; }&#xff0c;把它的所有元…

操作系统磁盘管理类问题

例题&#xff1a;在磁盘上存储数据的排列方式会影响1/0服务的总时间。假设每个磁道被划分成10个物理块&#xff0c;每个物理块存放1个逻辑记录。逻辑记录R1,R2....R10存放在同一个磁道上&#xff0c;记录的排列顺序如下表所示&#xff1a; 假定磁盘的旋转速度为10ms/周&#xf…

问界新M5交付,「975」组合站稳中国豪华智电定位

‍作者 |老缅 编辑 |德新 5月15日&#xff0c;问界新M5已正式开启全国用户交付。从网传图片可以看到&#xff0c;华为余承东以及赛力斯AITO问界BU总裁何利扬亲自出席了首批交车仪式。 4月23日&#xff0c;在不到1个月前&#xff0c;新M5发布。新M5共推出三款车型&#xff1a; …

Pikachu 靶场敏感信息泄露通关解析

前言 Pikachu靶场是一种常见的网络安全训练平台&#xff0c;用于模拟真实世界中的网络攻击和防御场景。它提供了一系列的实验室环境&#xff0c;供安全专业人士、学生和爱好者练习和测试他们的技能。 Pikachu靶场的目的是帮助用户了解和掌握网络攻击的原理和技术&#xff0c;…

你好 GPT-4o!

你好 GPT-4o&#xff01; OpenAI公司宣布推出 GPT-4o&#xff0c;这是OpenAI的新旗舰模型&#xff0c;可以实时对音频、视觉和文本进行推理。 GPT-4o&#xff08;“o”代表“o​​mni”&#xff09;是迈向更自然的人机交互的一步——它接受文本、音频、图像和视频的任意组合作…