使用C#的异步和依赖注入实现网络数据存储
详细解释
-
依赖注入(Dependency Injection):
ConfigureServices方法配置了服务的依赖注入。IDataProcessor接口与DataProcessor类绑定,IDbConnectionFactory接口与DbConnectionFactory类绑定。这样在程序运行时,依赖注入容器会提供这些接口的实现。
-
主程序入口(
Main方法):- 在
Main方法中,配置服务,创建服务提供者,并通过服务提供者获取IDataProcessor的实现实例来处理数据。
- 在
-
数据处理接口(
IDataProcessor和DataProcessor类):IDataProcessor是一个接口,定义了ProcessDataAsync方法,用于处理数据。DataProcessor类实现了IDataProcessor接口,负责从 API 获取数据、处理数据、保存数据到数据库并写入文件。
-
异步编程(
async和await):- 异步编程用于避免阻塞主线程。
FetchDataAsync方法从 API 获取数据,SaveDataToDatabaseAsync方法将数据异步保存到数据库。
- 异步编程用于避免阻塞主线程。
-
数据处理(
ProcessData方法):- 数据处理的逻辑将每个数据项的名称转换为大写,并计算值的长度。
-
文件操作(
WriteDataToFile方法):- 将处理后的数据写入到
output.txt文件中,每行包含 ID、名称和长度。
- 将处理后的数据写入到
-
SQLite 数据库操作:
- 使用
System.Data.SQLite进行数据库连接和操作。DbConnectionFactory类提供了创建数据库连接的方法,SaveDataToDatabaseAsync方法将处理后的数据存储到 SQLite 数据库中的ProcessedData表。
- 使用
-
错误处理:
- 使用
try-catch块来捕捉并处理可能的异常,并输出错误信息。
- 使用
using Microsoft.Extensions.DependencyInjection; // 引入依赖注入的命名空间 using Newtonsoft.Json; // 引入 JSON 处理的命名空间 using System; // 引入基本的系统功能 using System.Collections.Generic; // 引入泛型集合功能 using System.Data.SQLite; // 引入 SQLite 数据库操作的命名空间 using System.IO; // 引入文件操作的命名空间 using System.Net.Http; // 引入 HTTP 网络请求的命名空间 using System.Threading.Tasks; // 引入异步编程的命名空间namespace ComplexConsoleApp {class Program{static async Task Main(string[] args){// 配置服务var services = new ServiceCollection();ConfigureServices(services);var serviceProvider = services.BuildServiceProvider();// 获取 IDataProcessor 实现类的实例并处理数据var dataProcessor = serviceProvider.GetService<IDataProcessor>();await dataProcessor.ProcessDataAsync();}private static void ConfigureServices(IServiceCollection services){// 将 DataProcessor 注册为 IDataProcessor 的实现services.AddTransient<IDataProcessor, DataProcessor>();// 将 DbConnectionFactory 注册为 IDbConnectionFactory 的实现services.AddSingleton<IDbConnectionFactory, DbConnectionFactory>();}}// 数据处理接口public interface IDataProcessor{Task ProcessDataAsync(); // 异步处理数据}public class DataProcessor : IDataProcessor{private readonly IDbConnectionFactory _dbConnectionFactory;private const string ApiUrl = "https://api.example.com/data"; // API 数据的 URLpublic DataProcessor(IDbConnectionFactory dbConnectionFactory){_dbConnectionFactory = dbConnectionFactory;}public async Task ProcessDataAsync(){try{// 获取数据var data = await FetchDataAsync();// 处理数据var processedData = ProcessData(data);// 将数据保存到数据库await SaveDataToDatabaseAsync(processedData);// 将数据写入文件WriteDataToFile(processedData);}catch (Exception ex){// 捕捉并输出异常信息Console.WriteLine($"发生错误: {ex.Message}");}}private async Task<List<DataItem>> FetchDataAsync(){using (var client = new HttpClient()){// 发送 HTTP GET 请求并获取响应内容var response = await client.GetStringAsync(ApiUrl);// 将 JSON 响应内容转换为 DataItem 对象的列表return JsonConvert.DeserializeObject<List<DataItem>>(response);}}private List<ProcessedDataItem> ProcessData(List<DataItem> data){// 模拟数据处理var processedData = new List<ProcessedDataItem>();foreach (var item in data){// 将每个数据项的名称转换为大写,并计算值的长度processedData.Add(new ProcessedDataItem{Id = item.Id,Name = item.Name.ToUpper(),Value = item.Value.Length});}return processedData;}private async Task SaveDataToDatabaseAsync(List<ProcessedDataItem> data){using (var connection = _dbConnectionFactory.CreateConnection()){await connection.OpenAsync(); // 打开数据库连接var transaction = connection.BeginTransaction(); // 开始事务foreach (var item in data){// 创建 SQL 命令var command = connection.CreateCommand();command.Transaction = transaction;command.CommandText = "INSERT INTO ProcessedData (Id, Name, Value) VALUES (@Id, @Name, @Value)";command.Parameters.AddWithValue("@Id", item.Id);command.Parameters.AddWithValue("@Name", item.Name);command.Parameters.AddWithValue("@Value", item.Value);await command.ExecuteNonQueryAsync(); // 执行 SQL 命令}transaction.Commit(); // 提交事务}}private void WriteDataToFile(List<ProcessedDataItem> data){using (var writer = new StreamWriter("output.txt")){foreach (var item in data){// 将处理后的数据写入文件writer.WriteLine($"{item.Id}, {item.Name}, {item.Value}");}}}}// 数据库连接工厂接口public interface IDbConnectionFactory{SQLiteConnection CreateConnection(); // 创建 SQLite 连接}public class DbConnectionFactory : IDbConnectionFactory{private const string ConnectionString = "Data Source=database.db;Version=3;"; // 数据库连接字符串public SQLiteConnection CreateConnection(){return new SQLiteConnection(ConnectionString); // 创建并返回 SQLite 连接}}// 从 API 获取的原始数据项public class DataItem{public int Id { get; set; } // 数据项的 IDpublic string Name { get; set; } // 数据项的名称public string Value { get; set; } // 数据项的值}// 处理后的数据项public class ProcessedDataItem{public int Id { get; set; } // 数据项的 IDpublic string Name { get; set; } // 数据项的名称(转换为大写)public int Value { get; set; } // 数据项的值的长度} }
相关文章:
使用C#的异步和依赖注入实现网络数据存储
详细解释 依赖注入(Dependency Injection): ConfigureServices 方法配置了服务的依赖注入。IDataProcessor 接口与 DataProcessor 类绑定,IDbConnectionFactory 接口与 DbConnectionFactory 类绑定。这样在程序运行时,依赖注入容器…...
tomcat日志文件切割
文章目录 引言I 使用用crontab工具,定时执行任务II 通过Linux系统自带的切割工具logrotate来进行切割logrotate 简介用法结合crontab进行自定义的定时轮转操作III 基于其他日志框架进行分隔引言 tomcat 的 catalina.out 文件不会进行日志切割,当这个文件大于2G 时,会影响to…...
Python将Word文档转为PDF
使用python将word转pdf_py work转pdf-CSDN博客 掌握Python技巧:PDF文件的加密和水印处理-CSDN博客...
深入浅出链表
目录 1.链表的基本概念及结构 1.1基本概念 1.2结构 2.链表的分类 3.链表的实现(循环链表增删查改实现) 1.动态申请节点(结点)编辑 2.单链表打印 3.单链表尾插 4.单链表头插 5.单链表尾删 6.单链表头删 7.单链表查找 …...
Linux核心命令入门
Linux常用命令 文件管理文件目录管理文件查看编辑 系统管理网络管理hostnamehost/nslookuptraceroutenetstat列出所有端口 (包括监听和未监听的)列出所有处于监听状态的 Sockets显示每个协议的统计信息 硬件管理df(Disk Free)du(Disk Usage&a…...
腾讯无界微前端框架介绍
一、无界微前端框架概述 无界微前端框架是由腾讯团队推出的,旨在解决现有微前端方案中存在的问题,如适配成本高、样式隔离困难、运行性能不佳、页面白屏、子应用通信复杂、子应用保活机制缺乏等。 技术实现 无界微前端的核心技术是基于Web Component…...
Linux——网络(2)
一、通信 --- 不同主机上进程间的通信 1、IP和端口号 IP:标识网络中的一台主机 本质上 32位的整型数据 端口号: 标识某个进程 本质上 16位的整型数据 2、udp和tcp udp的特点: 1.无连接 2.不可靠 tcp的特点: 1.面…...
结合量子技术解决数据传输安全
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 接前篇:数采网关面…...
【Rust光年纪】提高开发效率:深入了解Rust语言中的数据库客户端和文件处理库
深入探索:Rust语言中多款数据库客户端与文件处理库详解 前言 在现代软件开发中,使用各种数据库和文件处理操作是非常常见的。Rust语言作为一种快速、安全、并发的系统编程语言,也拥有丰富的生态系统和库。本文将介绍几个用于Rust语言的数据…...
【自动驾驶】控制算法(一)绪论与前期准备
写在前面: 🌟 欢迎光临 清流君 的博客小天地,这里是我分享技术与心得的温馨角落。📝 个人主页:清流君_CSDN博客,期待与您一同探索 移动机器人 领域的无限可能。 🔍 本文系 清流君 原创之作&…...
CSDN创作一周年总结
一周年总结 文章目录 一周年总结我的第一篇文章这一年我收获到了什么?1.培养了逻辑能力2.形成了自己的知识库,知识网络3.功利性的收获 我的第一篇文章 不知不觉之间,也已经过去一年了。还记得第一次决定在csdn上写博客,是因为进入…...
World of Warcraft [CLASSIC] the Eye of Eternity [EOE] P1-P2
World of Warcraft [CLASSIC] the Eye of Eternity [EOE] 永恒之眼(蓝龙) 第一阶段 第二阶段 第三阶段 载具1-6技能介绍 World of Warcraft [CLASSIC] the Eye of Eternity [EOE]_永恒之眼 eoe-CSDN博客 永恒之眼怎么出副本呢,战斗结束&am…...
一键翻译全球:多语言支持下的英文翻译工具
随着科技的飞速发展,一系列英文翻译工具应运而生,它们以人工智能为驱动,极大地简化了跨语言交流的过程。本文将带您一窥英文翻译工具探索那些能够帮助我们跨越语言鸿沟的神奇工具。 1.福昕在线翻译 链接直达>>https://fanyi.pdf365.c…...
水战再起波澜,“怡宝”要下好怎样一盘棋?
不少投资者常把那些刚需性强、永远也不可能淘汰的产业称为“日不落产业”,从细分板块来看,水无疑具有一定代表性。农夫山泉掌门人钟晱晱曾直言:“我选择了一个日不落的产业,你永远要喝水,不可能不喝水。” 多年下来&a…...
使用maven快速生成打包文件3
这里再介绍一种打包方式,依赖包分开打包,直接将需要部署的文件打包成一个要锁文件,比如kafka-roma-bin.tar.gz,这里需要两个文件,一个pom2.xml,一个package.xml。 pom2.xml <?xml version"1.0&q…...
Excel技巧(一)
快捷键技巧 原文链接 选取某一行的数据直到最后一行:【CTRL SHIFT ↓ 】或者选取一行后按住SHIFT键,双击下边线就可以快速选取区域。 如果表格中有多行空行,可以先按CTRL SHIFT END,再按CTRL SHIFT 上下键调整,…...
C语言:文件复制
文本文件复制: #include<stdio.h>int main() {FILE* pFile1 NULL;FILE* pFile2 NULL;fopen_s(&pFile1,"D:\\11111.txt","r");fopen_s(&pFile2,"D:\\222.txt", "w");char c;while((cfgetc(pFile1))!EOF){f…...
谈谈建筑项目管理:类型、流程和工具
无论是在材料采购还是供应商管理方面,确保建筑项目按计划进行并控制在预算内始终是一项挑战。 如今,建筑项目管理正逐步采用软件驱动的方法来提升其效率。这一转型显著优化了项目规划、调度和资源配置,使建筑管理更加精确和高效。 什么是建…...
【Vue】生命周期函数
系列文章目录 第五章 生命周期函数 文章目录 系列文章目录 生命周期函数代表的是Vue实例,或者是Vue组件,在网页中各个生命阶段所执行的函数。生命周期函数可以分为创建阶段、挂载阶段、更新阶段以及卸载阶段。 创建阶段:setup挂载阶段&…...
C++系列-文件操作
文件操作 文件类型文本文件二进制文件 文件操作的三大类文件的打开方式ios::app(append)和 ios::ate(at end) 写文件写文件文件步骤读文件文件步骤二进制文件读写写一般数据写特殊数据 程序运行时产生的数据都属于临时数据,一旦程序运行完毕,就会释放&am…...
从视频到网格:基于Colmap与OpenMVS的自动化三维重建实战
1. 三维重建技术入门:从视频到网格的魔法之旅 想象一下,你手里有一段普通的手机视频,可能是绕着某个物体拍摄的简单环绕画面。通过今天要介绍的技术,这段视频可以神奇地变成一个带纹理的三维模型,就像变魔术一样。这就…...
保姆级避坑指南:在Ubuntu 20.04 + ROS Noetic下,用Livox Mid360雷达和PX4无人机做Gazebo仿真建图
保姆级避坑指南:Ubuntu 20.04 ROS Noetic下Livox Mid360雷达与PX4无人机Gazebo仿真建图全流程解析 当你在深夜的实验室里第三次面对Gazebo的黑屏和ROS的红色报错时,是否想过——为什么别人的仿真流程行云流水,而自己的每一步都像在拆炸弹&am…...
Verilog新手避坑指南:用Icarus Verilog写Testbench时,$dumpfile和$dumpvars这两行到底有什么用?
Verilog仿真核心机制解析:$dumpfile与$dumpvars的底层逻辑与实战技巧 刚接触Verilog仿真的开发者,往往会在Testbench中看到这两行神秘的代码: $dumpfile("waveform.vcd"); $dumpvars(0, top_module);它们像黑魔法咒语一样被复制粘贴…...
rasterizeHTML.js API完全手册:从drawHTML到drawURL的完整使用指南
rasterizeHTML.js API完全手册:从drawHTML到drawURL的完整使用指南 【免费下载链接】rasterizeHTML.js Renders HTML into the browsers canvas 项目地址: https://gitcode.com/gh_mirrors/ra/rasterizeHTML.js rasterizeHTML.js是一款强大的JavaScript库&am…...
自动控制理论(12)——控制系统校正的工程实践与优化
1. 控制系统校正的工程意义 在工业自动化领域,控制系统就像人体的神经系统,需要精确调节才能保证设备稳定运行。想象一下化工反应釜的温度控制:如果响应太慢会导致反应不充分,响应太快又可能引发剧烈振荡。这就是为什么我们需要校…...
终极虚拟机检测指南:如何用VMDE轻松识别虚拟环境
终极虚拟机检测指南:如何用VMDE轻松识别虚拟环境 【免费下载链接】VMDE Source from VMDE paper, adapted to 2015 项目地址: https://gitcode.com/gh_mirrors/vm/VMDE 你是否曾经好奇过,你的电脑是否运行在虚拟环境中?或者你是否需要…...
智能搜索系统构建:BAAI/bge-m3语义召回模块部署教程
智能搜索系统构建:BAAI/bge-m3语义召回模块部署教程 想自己搭建一个能“理解”你意思的智能搜索系统吗?比如,你输入“我喜欢看书”,它能精准找到“阅读使我快乐”这样的相关文档,而不是机械地匹配“书”这个关键词。今…...
别再只调参了!用眼动、多模态数据真正提升你的脑电AI模型效果
别再只调参了!用眼动、多模态数据真正提升你的脑电AI模型效果 当你的脑电模型准确率卡在85%的瓶颈期,是否想过问题可能不在参数调整,而在于数据维度本身?去年我们团队在情绪识别项目中引入眼动数据后,模型F1值直接从0…...
跨平台资源捕获利器:3大核心功能实现全网内容轻松下载
跨平台资源捕获利器:3大核心功能实现全网内容轻松下载 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 你是否曾为…...
Windows平台下基于CMake与VS2022的SOEM EtherCAT主站开发环境搭建指南
1. 环境准备:工欲善其事必先利其器 在Windows下玩转EtherCAT主站开发,首先得把工具链配齐。我当年第一次搭环境时,光是找齐这些工具就花了半天时间,现在把踩坑经验一次性打包给你。 必备三件套: Visual Studio 2022&am…...
