1.需求:

计算滑动时间下的1小时、3小时、6小时、12小时、24小时降水数据,统计这个时间下的分钟级降水数据

2.分析

第一版本:降水分钟级数据保存时间不长,保存太多意义不大,以更新的形式来保存这些统计数据效果会比较好,使用管道先进先出的原则每5分钟取一次数据,每次只需要取近5分钟的数据即可,设置管道长度分别为12组、36组、72组,144组和288组降水数据,取够数据之后将之前第一组的数据自动去除即可

版本分析:

优点:基本能达到在一次过程中的数据统计功能,而且占用内存很小,数据整体运行比较顺畅,每次取的数据量比较小

缺点:数据统计不准确,虽然用了定时器的定数回调方法来处理数据,仍然存在数据统计不准的情况,这个问题初步判定为天擎数据的后期更新,但是管道内的数据没有更新导致数据存在差异的问题,数据的准确性不能保证,弃用

第二个版本:保留每5分钟更新一次数据的频率,将近1小时、3小时、6小时、12小时、24小时降水数据直接进行统计,统计后的数据保存下来即可

版本分析:

优点:数据的准确性能保证,数据没有差异

缺点:数据的体量比较大,内存占用比较大,在统计过程中存在内存占用很高的情况

版本更新:

在每次定时回调统计数据的方法中将每次调用后的法中对已经弃用的一些变量和占用内存较高的变量进行GC处理

更新分析:

优点:数据统计的内存占比在每次统计完成后会清理掉,占用的内存会比较小

缺点:每次都要统计很多数据,有些站点的数据在处理的时候会在时间段内漏报,在统计时会出现站点报错,导致站点数据统计不上的情况,在统计的时候加上判断

最终效果:

using System.Data;
using System.Data.SqlClient;
using System.Text;
using CMISS_DATA_Helper;
using Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;class Program
{private static readonly Dictionary<string, decimal> hourlyAccumulator_1 = new Dictionary<string, decimal>();private static readonly Dictionary<string, decimal> hourlyAccumulator_3 = new Dictionary<string, decimal>();private static readonly Dictionary<string, decimal> hourlyAccumulator_6 = new Dictionary<string, decimal>();private static readonly Dictionary<string, decimal> hourlyAccumulator_12 = new Dictionary<string, decimal>();private static readonly Dictionary<string, decimal> hourlyAccumulator_24 = new Dictionary<string, decimal>();private static readonly object lockObj = new object();private static Timer timer;private static string DbConnectionString = "Data Source=.;Initial Catalog=Meteorological_Bz;User Id=sa;Password=sa123...;MultipleActiveResultSets=True";// 配置参数private static int IntervalMinutes = 5;private static int WindowSize_1 = (60 / IntervalMinutes) * 1; // 1小时 = 12 * 5分钟private static int WindowSize_3 = (60 / IntervalMinutes) * 3;private static int WindowSize_6 = (60 / IntervalMinutes) * 6;private static int WindowSize_12 = (60 / IntervalMinutes) * 12;private static int WindowSize_24 = (60 / IntervalMinutes) * 24;private static string columns = "Station_Id_C,UPDATE_TIME,Datetime,PRE";private static string url = "";//天擎接口private static string AdminCode = "110000";//区划码private static string[] stationIds = getStations();//获取站点数据
static JObject valueconfig;
static async Task Main(string[] args)
{// 初始化站点数据(假设已知400个站点ID)System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);using (System.IO.StreamReader file = new System.IO.StreamReader(AppDomain.CurrentDomain.BaseDirectory + "dataconfig.json", Encoding.UTF8)){valueconfig = JsonConvert.DeserializeObject<JObject>(file.ReadToEnd());file.Close();}DbConnectionString = valueconfig["conn"].ToString();if (valueconfig["stationIds"].ToString() != string.Empty) stationIds = valueconfig["stationIds"].ToString().Split(",");columns = valueconfig["columns"].ToString();url = valueconfig["url"].ToString();AdminCode = valueconfig["AdminCode"].ToString();IntervalMinutes = int.Parse(valueconfig["IntervalMinutes"].ToString());InitializeAccumulator(stationIds);// 初始化定时器(立即启动,每5分钟执行)timer = new Timer(ProcessWeatherData, null, 0, IntervalMinutes * 60 * 1000);Console.WriteLine("服务已启动,按任意键退出...");Console.ReadKey();timer.Dispose();
}
// 初始化累加器(所有站点归零)
private static void InitializeAccumulator(string[] stationIds)
{lock (lockObj){Console.WriteLine("初始化站点!");foreach (var id in stationIds){hourlyAccumulator_1[id] = 0;hourlyAccumulator_3[id] = 0;hourlyAccumulator_6[id] = 0;hourlyAccumulator_12[id] = 0;hourlyAccumulator_24[id] = 0;}}
}// 定时器回调方法private static async void ProcessWeatherData(object state){try{InitializeAccumulator(stationIds);// 1. 获取API数据var currentData_1 = await FetchWeatherDataAsync(60 * 1);var currentData_3 = await FetchWeatherDataAsync(60 * 3);var currentData_6 = await FetchWeatherDataAsync(60 * 6);var currentData_12 = await FetchWeatherDataAsync(60 * 12);var currentData_24 = await FetchWeatherDataAsync(60 * 24);lock (lockObj){try{foreach (var kvp in currentData_1){if (hourlyAccumulator_1.ContainsKey(kvp.Key)){hourlyAccumulator_1[kvp.Key] += kvp.Value;}else{hourlyAccumulator_1.Add(kvp.Key, kvp.Value);}}//Console.WriteLine($"{DateTime.Now}: 1小时降水已统计");}catch (Exception ex){Console.WriteLine($"1小时降水已统计异常{ex.Message}");}try{foreach (var kvp in currentData_3){if (hourlyAccumulator_3.ContainsKey(kvp.Key)){hourlyAccumulator_3[kvp.Key] += kvp.Value;}else{hourlyAccumulator_3.Add(kvp.Key, kvp.Value);}}}catch (Exception ex){Console.WriteLine($"3小时降水已统计异常{ex.Message}");}try{foreach (var kvp in currentData_6){if (hourlyAccumulator_6.ContainsKey(kvp.Key)){hourlyAccumulator_6[kvp.Key] += kvp.Value;}else{hourlyAccumulator_6.Add(kvp.Key, kvp.Value);}}}catch (Exception ex){Console.WriteLine($"6小时降水已统计异常{ex.Message}");}try{foreach (var kvp in currentData_12){if (hourlyAccumulator_12.ContainsKey(kvp.Key))hourlyAccumulator_12[kvp.Key] += kvp.Value;else{hourlyAccumulator_12.Add(kvp.Key, kvp.Value);}}}catch (Exception ex){Console.WriteLine($"12小时降水已统计异常{ex.Message}");}try{foreach (var kvp in currentData_24){if (hourlyAccumulator_24.ContainsKey(kvp.Key))hourlyAccumulator_24[kvp.Key] += kvp.Value;else{hourlyAccumulator_24.Add(kvp.Key, kvp.Value);}}}catch (Exception ex){Console.WriteLine($"24小时降水已统计异常{ex.Message}");}// 4. 更新数据库UpdateDatabase(hourlyAccumulator_1, hourlyAccumulator_3, hourlyAccumulator_6, hourlyAccumulator_12, hourlyAccumulator_24);Console.WriteLine($"{DateTime.Now}:近小时数据已更新");//5.释放内存try{Console.WriteLine($"{DateTime.Now}:释放内存");currentData_1.Clear();currentData_1.TrimExcess();currentData_1 = null;currentData_3.Clear();currentData_3.TrimExcess();currentData_3 = null;currentData_6.Clear();currentData_6.TrimExcess();currentData_6 = null;currentData_12.Clear();currentData_12.TrimExcess();currentData_12 = null;currentData_24.Clear();currentData_24.TrimExcess();currentData_24 = null;hourlyAccumulator_1.Clear();hourlyAccumulator_1.TrimExcess();hourlyAccumulator_3.Clear();hourlyAccumulator_3.TrimExcess();hourlyAccumulator_6.Clear();hourlyAccumulator_6.TrimExcess();hourlyAccumulator_12.Clear();hourlyAccumulator_12.TrimExcess();hourlyAccumulator_24.Clear();hourlyAccumulator_24.TrimExcess();GC.Collect();GC.WaitForPendingFinalizers();GC.Collect();}catch (Exception ex){Console.WriteLine(ex.ToString());}}}catch (Exception ex){Console.WriteLine($"处理失败: {ex.Message}");}}private static async Task<Dictionary<string, decimal>> FetchWeatherDataAsync(int minute){
//获取天擎数据,并异步返回Dictionary数据return data;
}private static void UpdateDatabase(Dictionary<string, decimal> data_1, Dictionary<string, decimal> data_3, Dictionary<string, decimal> data_6, Dictionary<string, decimal> data_12, Dictionary<string, decimal> data_24){
//更新数据库
}
}

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图片合并pdf

文章目录 背景目标实现下载 背景 整合&#xff1a; 将零散的图片集合成一个单一文件。有序化&#xff1a; 固定图片的排列顺序。标准化&#xff1a; 转换为通用、兼容性强的PDF格式。高效管理&#xff1a; 便于存储、查找、分享和传输。正式化/文档化&#xff1a; 满足提交、报…

【vue3+js】文件下载方法整理

前端文件下载方式 引言 在前端开发中,文件下载是一个常见的需求。后端可能以不同的方式返回文件数据,前端需要根据不同的返回类型采用相应的处理方式。本文将总结几种常见的后端返回类型及对应的前端处理方案,主要基于Vue3和JavaScript环境。 一、后端返回文件URL 场景描…

MicrobiomeStatPlots | 森林图教程Forest plot tutorial

视频讲解https://www.bilibili.com/video/BV1mA3yzEEnc/森林图简介什么是森林图&#xff1f;参考&#xff1a;https://mp.weixin.qq.com/s/vwNf_sFlmhp7DeSYaQ3NxQ森林图是以统计指标和统计分析方法为基础&#xff0c;用数值运算结果绘制出的图形。它在平面直角坐标系中&#x…

vscode 打开项目时候,有部分外部依赖包找不到定义或者声明,但是能使用cmake正常编译并且运行

解决&#xff1a;是依赖路径的问题&#xff0c;先看includePath对不对&#xff0c;但是有时候会依赖外部文件&#xff0c;这时候入股cmake编译能够听过&#xff0c; 说明编译器能够找到依赖路径&#xff0c; 但是vscode的 IntelliSense 找不到依赖路径 → 导致编辑器提示错误、…

nginx:SSL_CTX_use_PrivateKey failed

SSL_CTX_use_PrivateKey("/home/nginx-vue/cret/*.com.key") failed (SSL: error:0B080074:x509 certificate routines:x509_check_private_key:key values mismatch) Nginx 尝试加载私钥文件时失败&#xff0c;原因是&#xff1a;证书与私钥不匹配 问题本质 SSL 证…

Docker 基于 Cgroups 实现资源限制详解【实战+源码】

本文将带你深入理解 Docker 如何借助 Linux Cgroups 实现对内存、CPU 等系统资源的精细化控制&#xff0c;并提供完整演示与图解、Compose 配置模板和资源包下载&#xff0c;适合初学者与工程师深入学习与实战。 文章目录 一、什么是 Cgroups&#xff1f;为什么对容器如此关键…

Linux中的系统日志(Rsyslog)

一、实验环境主机名系统网络适配器IP地址serverarhel9NAT模式172.25.254.11/24serverbrhel9NAT模式172.25.254.22/24二、Rsyslog的基本参数&#xff08;1&#xff09;安装rsyslog&#xff08;2&#xff09;rsyslog的服务名称&#xff08;3&#xff09;rsyslog的主配置文件rsysl…

Spring Boot + Thymeleaf + RESTful API 前后端整合完整示例

关键词&#xff1a;Spring Boot、Thymeleaf、RESTful API、前后端整合、用户管理 ✅ 功能概述 本文将为你提供一个完整的 Spring Boot Thymeleaf RESTful API 的前后端整合项目&#xff0c;实现以下功能&#xff1a; 模块功能用户管理查看用户列表、新增用户、删除用户后端…

从零开始的MySQL学习

MySQL 从零开始的MySQL学习 第一节 数据库 重点&#xff1a;数据库通过SQL等标准语言进行动作&#xff0c;数据库的概念、分类&#xff0c;数据管理系统&#xff08;操纵和管理数据库的大型软件&#xff09; 数据库&#xff08;Database&#xff09; 是按照数据结构来组织、存储…

Docker 高级管理--Dockerfile镜像制作

二:Dockerfile 语法基础 1:基础指令 (1)FROM 指定基础镜像&#xff0c;所有的 Dockerfile 都必须以 FROM 指令开头&#xff0c;它定义了新镜像基于哪个基础镜像构建。 FRoM ubuntu:20.04 (2)MAINTAINER(已奔用&#xff0c;推荐使用LABEL) 用于指定镜像的维护者信息。不过在较…

LeetCode 692题解 | 前K个高频单词

前K个高频单词一、题目链接二、题目三、分析四、代码一、题目链接 692.前K个高频单词 二、题目 三、分析 本题目我们利用map统计出次数以后&#xff0c;返回的答案应该按单词出现频率由高到低排序&#xff0c;有一个特殊要求&#xff0c;如果不同的单词有相同出现频率&#…

C++ 中的 std::bind 用法

在现代 C++ 编程中,std::bind 是一个非常强大但常常被误解的工具。它允许我们将函数(包括成员函数)、参数进行绑定,并生成一个新的可调用对象。这在编写异步回调、事件处理、适配器模式等场景中非常有用。 🔧 一、std::bind 是什么? std::bind 是定义在 <functiona…

Spring Boot秒级冷启动方案:阿里云FC落地实战(含成本对比)

Spring Boot秒级冷启动方案&#xff1a;阿里云FC落地实战&#xff08;含成本对比&#xff09;一、冷启动痛点与FC核心优势1. 传统Spring Boot冷启动瓶颈2. 阿里云FC核心能力二、秒级冷启动架构设计1. 整体架构2. 关键组件选型三、5大核心优化策略1. 应用瘦身&#xff08;JAR包精…

搜索引擎vs向量数据库:LangChain混合检索架构实战解析

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。一、LangChain搜索工具实战&#xff1a;集成DuckDuckGo实现实时信息查询 核心场景&#xff1a;解决大模型知识滞后问题&#xff0c;通过搜索引擎获取实…

【算法】贪心算法:将数组和减半的最少操作次数C++

文章目录前言题目解析算法原理代码示例策略证明前言 题目的链接&#xff0c;大家可以先试着去做一下再来看一下思路。2208. 将数组和减半的最少操作次数 - 力扣&#xff08;LeetCode&#xff09; 题目解析 要认真去把题目看一遍&#xff0c;画出题目中的有用信息。 示例一定是…

git异常退出,应该是内存不足

这次下载代码&#xff1a; 公司虚拟机到了一定步骤&#xff0c;肯定退出。而家里的虚拟机则完全正常。我把家里的虚拟机复制到公司&#xff0c;还是崩溃。 差异在哪里&#xff1f;公司电脑虚拟机内存设置为10G&#xff0c;家里的16。因为家里电脑64G内存。 后来确认&#xff…

机器学习13——支持向量机下

支持向量机下 非线性支持向量机&#xff08;Non-linear SVMs&#xff09;详解 核心思想 当数据在原始空间线性不可分时&#xff0c;通过**核技巧&#xff08;Kernel Trick&#xff09;**将数据映射到高维特征空间&#xff0c;使其在该空间中线性可分。 比如以下的样本在一维空间…

GPT-4和Claude哪个好

选择GPT-4还是Claude?这就像在问“苹果还是橙子哪个更好”——‌答案完全取决于你的具体需求‌。两者都是顶尖大语言模型,但各有特色。 我为你做了详细对比,帮你快速定位哪个更适合你: 🧠 核心能力对比 特性GPT-4 (OpenAI)Claude (Anthropic)‌语言理解/推理‌顶尖水平,…

RHCE考试 ——笔记

RHCE模拟测试exam_start ehcerht-vmctl start all考前说明• 请勿更改 IP 地址。DNS 解析完整主机名&#xff0c;同时也解析短名称。• 所有系统的 root 密码都是 redhat• Ansible 控制节点上已创建用户账户 devops。可以使用 ssh 访问• 所需的所有镜像保存在镜像仓库 utilit…

信创 CDC 实战 | TiDB 实时入仓难点与解决方案解析(以 ClickHouse 为例)

国产数据库加速进入核心系统&#xff0c;传统同步工具却频频“掉链子”。本系列文章聚焦 OceanBase、GaussDB、TDSQL、达梦等主流信创数据库&#xff0c;逐一拆解其日志机制与同步难点&#xff0c;结合 TapData 的实践经验&#xff0c;系统讲解从 CDC 捕获到实时入仓&#xff0…