async await 异步下载 异步代码加锁 lock 异步缓存

FTP异步下载代码:

  1. /// <summary>
  2. /// 异步下载文件
  3. /// </summary>
  4. /// <param name="ftpPath">ftp路径</param>
  5. /// <param name="ftpUserId">用户名</param>
  6. /// <param name="ftpPassword">密码</param>
  7. /// <param name="relativeFilePath">文件相对路径</param>
  8. public static async Task<MemoryStream> DownloadFileAsync(string ftpPath, string ftpUserId, string ftpPassword, string relativeFilePath)
  9. {
  10. FtpWebRequest request = null;
  11.  
  12. try
  13. {
  14. LogTimeUtil log = new LogTimeUtil();
  15. request = (FtpWebRequest)WebRequest.Create(new Uri(Path.Combine(ftpPath, relativeFilePath).Replace("\\", "/")));
  16. request.Credentials = new NetworkCredential(ftpUserId, ftpPassword);
  17. request.Method = "RETR";
  18. FtpWebResponse response = (FtpWebResponse)(await request.GetResponseAsync());
  19. Stream responseStream = response.GetResponseStream();
  20. MemoryStream stream = new MemoryStream();
  21. byte[] bArr = new byte[1024 * 1024];
  22. int size = await responseStream.ReadAsync(bArr, 0, (int)bArr.Length);
  23. while (size > 0)
  24. {
  25. stream.Write(bArr, 0, size);
  26. size = await responseStream.ReadAsync(bArr, 0, (int)bArr.Length);
  27. }
  28. stream.Seek(0, SeekOrigin.Begin);
  29. responseStream.Close();
  30.  
  31. log.LogTime("FtpUtil.DownloadFileAsync 下载 filePath=" + relativeFilePath);
  32. return stream;
  33. }
  34. catch (Exception ex)
  35. {
  36. request.Abort();
  37. LogUtil.Error(ex);
  38. }
  39.  
  40. return null;
  41. }

异步缓存代码:

  1. /// <summary>
  2. /// 异步获取并缓存数据
  3. /// </summary>
  4. /// <param name="cacheKey">键</param>
  5. /// <param name="func">在此方法中初始化数据</param>
  6. /// <param name="expirationSeconds">缓存过期时间(秒),0表示永不过期</param>
  7. /// <param name="refreshCache">立即刷新缓存</param>
  8. public static async Task<T> TryGetValueAsync<T>(string cacheKey, Func<Task<T>> func, int expirationSeconds = 0, bool refreshCache = false)
  9. {
  10. string pre = "CacheHelper.TryGetValueAsync<T>";
  11. SemaphoreSlim sem = _dictSemaphoresForReadCache.GetOrAdd(pre + cacheKey, new SemaphoreSlim(1, 1));
  12. await sem.WaitAsync();
  13.  
  14. try
  15. {
  16. object cacheValue = HttpRuntime.Cache.Get(cacheKey);
  17. if (cacheValue != null)
  18. {
  19. return (T)cacheValue;
  20. }
  21. else
  22. {
  23. T value = await func();
  24. if (expirationSeconds > 0)
  25. {
  26. HttpRuntime.Cache.Insert(cacheKey, value, null, DateTime.Now.AddSeconds(expirationSeconds), Cache.NoSlidingExpiration);
  27. }
  28. else
  29. {
  30. HttpRuntime.Cache.Insert(cacheKey, value);
  31. }
  32. return value;
  33. }
  34. }
  35. catch (Exception ex)
  36. {
  37. LogUtil.Error(ex);
  38. return default(T);
  39. }
  40. finally
  41. {
  42. sem.Release();
  43. }
  44. }

Web API 异步下载接口:

  1. /// <summary>
  2. /// 文件下载
  3. /// </summary>
  4. /// <param name="filePath">文件存储相对路径</param>
  5. [HttpGet]
  6. [Route("DownloadFileByPath")]
  7. public async Task<HttpResponseMessage> DownloadFileByPath(string filePath)
  8. {
  9. HttpResponseMessage response = new HttpResponseMessage();
  10.  
  11. try
  12. {
  13. LogTimeUtil log = new LogTimeUtil();
  14. string fileName = Path.GetFileName(filePath);
  15.  
  16. if (FtpUtil.FileExists(_ftpPath, _ftpUserId, _ftpPassword, filePath))
  17. {
  18. byte[] bArr = await CacheHelper.TryGetValueAsync("DF9165DE189149258B34C405A2A7D7D1" + filePath, async () =>
  19. {
  20. MemoryStream ms = await FtpUtil.DownloadFileAsync(_ftpPath, _ftpUserId, _ftpPassword, filePath);
  21. return ms.ToArray();
  22. }, 180);
  23.  
  24. response.Content = new ByteArrayContent(bArr);
  25. response.Content.Headers.ContentLength = bArr.Length;
  26. response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
  27. response.Content.Headers.ContentDisposition.FileName = fileName;
  28. response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
  29. }
  30. else
  31. {
  32. LogUtil.Error("DownloadFileByPath 错误:文件不存在");
  33. return new HttpResponseMessage(HttpStatusCode.NotFound);
  34. }
  35. log.LogTime("CommonController.DownloadFileByPath 下载 filePath=" + filePath);
  36. }
  37. catch (Exception ex)
  38. {
  39. LogUtil.Error(ex, "DownloadFileByPath 错误");
  40. return new HttpResponseMessage(HttpStatusCode.NotFound);
  41. }
  42.  
  43. return response;
  44. }

async await 异步下载 异步代码加锁 lock 异步缓存的更多相关文章

  1. [每日一题]面试官问:Async/Await 如何通过同步的方式实现异步?

    关注「松宝写代码」,精选好文,每日一题 ​时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...

  2. 已配置好的vue全家桶项目router,vuex,api,axios,vue-ls,async/await,less下载即使用

    github 地址: https://github.com/liangfengbo/vue-cli-project 点击进入 vue-cli-project 已构建配置好的vuejs全家桶项目,统一管 ...

  3. 温故知新,CSharp遇见异步编程(Async/Await),聊聊异步编程最佳做法

    什么是异步编程(Async/Await) Async/Await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁.易懂.易维护的异步代码. Async/Await是C# 5引入的关键字,用以 ...

  4. [C#] 走进异步编程的世界 - 开始接触 async/await

    走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async/await,但在控制台输出示例时经常会采用 C# 6.0 的 $&qu ...

  5. 走进异步编程的世界 - 开始接触 async/await

    [C#] 走进异步编程的世界 - 开始接触 async/await   走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async ...

  6. [C#] 走进异步编程的世界 - 开始接触 async/await(转)

    原文链接:http://www.cnblogs.com/liqingwen/p/5831951.html 走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 ...

  7. .NET 基于任务的异步模式(Task-based Asynchronous Pattern,TAP) async await

    本文内容 概述 编写异步方法 异步程序中的控制流 API 异步方法 线程 异步和等待 返回类型和参数 参考资料 下载 Demo 下载 Demo TPL 与 APM 和 EAP 结合(APM 和 EAP ...

  8. 【C# TAP 异步编程】三、async\await的运作机理详解

    [原创] 本文只是个人笔记,很多错误,欢迎指出. 环境:vs2022  .net6.0 C#10 参考:https://blog.csdn.net/brook_shi/article/details/ ...

  9. How Javascript works (Javascript工作原理) (四) 事件循环及异步编程的出现和 5 种更好的 async/await 编程方式

    个人总结: 1.讲解了JS引擎,webAPI与event loop合作的机制. 2.setTimeout是把事件推送给Web API去处理,当时间到了之后才把setTimeout中的事件推入调用栈. ...

  10. C# 异步编程(async&await)

    同步:同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去 异步:异步是指进程不需要一直等下去,而是继续执行下面的操作 ...

随机推荐

  1. 实例讲解C++连接各种数据库,包含SQL Server、MySQL、Oracle、ACCESS、SQLite 和 PostgreSQL、MongoDB 数据库

    C++ 是一种通用的编程语言,可以使用不同的库和驱动程序来连接各种数据库.以下是一些示例代码,演示如何使用 C++ 连接 SQL Server.MySQL.Oracle.ACCESS.SQLite 和 ...

  2. R数据分析:集成学习方法之随机生存森林的原理和做法,实例解析

    很久很久以前给大家写过决策树,非常简单明了的算法.今天给大家写随机(生存)森林,随机森林是集成了很多个决策数的集成模型.像随机森林这样将很多个基本学习器集合起来形成一个更加强大的学习器的这么一种集成思 ...

  3. Spyder5老是闪退报错 "Blowfish has been deprecated "的解决方法

    目录 一.前言 我的运行环境 二.解读报错 三.解决方法 四.打开spyder5 一.前言 本人在学习python时图省事选择直接安装Anaconda3,用spyder5来进行学习,可是比较蛋疼的是安 ...

  4. ES到底是个什么东西

    概念:全文检索服务器(是基于Lucene开发的全文检索服务器),它可以近乎实时存储.检索数据,底层仍然是Lucene来实现的所以索引和搜索功能,他的目的是通过的简单的RESTFul API 来隐藏Lu ...

  5. 【UniApp】-uni-app-内置组件

    前言 好,经过上个章节的介绍完毕之后,了解了一下 uni-app-全局数据和局部数据 那么了解完了uni-app-全局数据和局部数据之后,这篇文章来给大家介绍一下 UniApp 中内置组件 首先不管三 ...

  6. C++ Qt开发:字符串QString容器

    在Qt框架中,QString 是一个强大而灵活的字符串容器,专为处理 Unicode 字符而设计.它提供了许多方便的方法来操作和处理字符串,使得在跨平台开发中能够轻松地进行文本操作.QString 是 ...

  7. 【YOLOv5】实现扑克牌的点数识别

    前言 其实年初的时候,我也跟着别人的源码,用 Tensoflow 实现过扑克牌的目标检测.虽然也通过博文的方式记录了,但是那个项目使用的 TF 版本比较旧,自身对 TF 并不熟.后期如果说要升级或修改 ...

  8. 12 HTTP的实体数据

    目录 数据类型和编码 HTTP协议为什么要关心 body MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型 HTTP 常用数据类型 MIM ...

  9. 2023 年最后一波工具安利「GitHub 热点速览」

    2023 年还有两周就要接近尾声了,2023 年的热点速览还有一波工具好安利:比如上周推荐之后上了热榜的远程调试工具 page-spy-web,让调试像呼吸一般自然方便:还有轻量级的搜索引擎 oram ...

  10. 数字孪生和GIS融合:激发数字孪生技术的进步潜力

    数字孪生技术和地理信息系统(GIS)的融合,为数字孪生领域带来了巨大的进步和创新.这种强大的联合不仅扩展了数字孪生技术的应用领域,还提供了更全面.更精确的数据支持,从而推动了数字孪生技术的发展和应用. ...