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

FTP异步下载代码:

/// <summary>
/// 异步下载文件
/// </summary>
/// <param name="ftpPath">ftp路径</param>
/// <param name="ftpUserId">用户名</param>
/// <param name="ftpPassword">密码</param>
/// <param name="relativeFilePath">文件相对路径</param>
public static async Task<MemoryStream> DownloadFileAsync(string ftpPath, string ftpUserId, string ftpPassword, string relativeFilePath)
{
FtpWebRequest request = null; try
{
LogTimeUtil log = new LogTimeUtil();
request = (FtpWebRequest)WebRequest.Create(new Uri(Path.Combine(ftpPath, relativeFilePath).Replace("\\", "/")));
request.Credentials = new NetworkCredential(ftpUserId, ftpPassword);
request.Method = "RETR";
FtpWebResponse response = (FtpWebResponse)(await request.GetResponseAsync());
Stream responseStream = response.GetResponseStream();
MemoryStream stream = new MemoryStream();
byte[] bArr = new byte[1024 * 1024];
int size = await responseStream.ReadAsync(bArr, 0, (int)bArr.Length);
while (size > 0)
{
stream.Write(bArr, 0, size);
size = await responseStream.ReadAsync(bArr, 0, (int)bArr.Length);
}
stream.Seek(0, SeekOrigin.Begin);
responseStream.Close(); log.LogTime("FtpUtil.DownloadFileAsync 下载 filePath=" + relativeFilePath);
return stream;
}
catch (Exception ex)
{
request.Abort();
LogUtil.Error(ex);
} return null;
}

异步缓存代码:

/// <summary>
/// 异步获取并缓存数据
/// </summary>
/// <param name="cacheKey">键</param>
/// <param name="func">在此方法中初始化数据</param>
/// <param name="expirationSeconds">缓存过期时间(秒),0表示永不过期</param>
/// <param name="refreshCache">立即刷新缓存</param>
public static async Task<T> TryGetValueAsync<T>(string cacheKey, Func<Task<T>> func, int expirationSeconds = 0, bool refreshCache = false)
{
string pre = "CacheHelper.TryGetValueAsync<T>";
SemaphoreSlim sem = _dictSemaphoresForReadCache.GetOrAdd(pre + cacheKey, new SemaphoreSlim(1, 1));
await sem.WaitAsync(); try
{
object cacheValue = HttpRuntime.Cache.Get(cacheKey);
if (cacheValue != null)
{
return (T)cacheValue;
}
else
{
T value = await func();
if (expirationSeconds > 0)
{
HttpRuntime.Cache.Insert(cacheKey, value, null, DateTime.Now.AddSeconds(expirationSeconds), Cache.NoSlidingExpiration);
}
else
{
HttpRuntime.Cache.Insert(cacheKey, value);
}
return value;
}
}
catch (Exception ex)
{
LogUtil.Error(ex);
return default(T);
}
finally
{
sem.Release();
}
}

Web API 异步下载接口:

/// <summary>
/// 文件下载
/// </summary>
/// <param name="filePath">文件存储相对路径</param>
[HttpGet]
[Route("DownloadFileByPath")]
public async Task<HttpResponseMessage> DownloadFileByPath(string filePath)
{
HttpResponseMessage response = new HttpResponseMessage(); try
{
LogTimeUtil log = new LogTimeUtil();
string fileName = Path.GetFileName(filePath); if (FtpUtil.FileExists(_ftpPath, _ftpUserId, _ftpPassword, filePath))
{
byte[] bArr = await CacheHelper.TryGetValueAsync("DF9165DE189149258B34C405A2A7D7D1" + filePath, async () =>
{
MemoryStream ms = await FtpUtil.DownloadFileAsync(_ftpPath, _ftpUserId, _ftpPassword, filePath);
return ms.ToArray();
}, 180); response.Content = new ByteArrayContent(bArr);
response.Content.Headers.ContentLength = bArr.Length;
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = fileName;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
}
else
{
LogUtil.Error("DownloadFileByPath 错误:文件不存在");
return new HttpResponseMessage(HttpStatusCode.NotFound);
}
log.LogTime("CommonController.DownloadFileByPath 下载 filePath=" + filePath);
}
catch (Exception ex)
{
LogUtil.Error(ex, "DownloadFileByPath 错误");
return new HttpResponseMessage(HttpStatusCode.NotFound);
} return response;
}

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. Netty源码学习4——服务端是处理新连接的&netty的reactor模式

    系列文章目录和关于我 零丶引入 在前面的源码学习中,梳理了服务端的启动,以及NioEventLoop事件循环的工作流程,并了解了Netty处理网络io重要的Channel ,ChannelHandle ...

  2. OpenAI宫斗反转反转再反转,到底是资本任性还是人性扭曲?

    最近OpenAI发生了一件大事,创始人山姆·奥特曼被董事会开除了,这在AI界引起了轩然大波. 事件经过 我们先来捋一下事件经过,时间以美国旧金山当地时间为准. 11月17日 11月17日12点(北京时 ...

  3. MySQL 出现 Error 1114 (HY000) The table is full 的解决方法

    版权声明:原创作品,谢绝转载!否则将追究法律责任. ----- 作者:kirin MySQL 出现 The table is full 只有一个原因,对应的表数据容量达到系统上限 . 这个问题可能是2 ...

  4. 自学day7 数组

    typora-copy-images-to: media 数组 一.概念 对象中可以通过键值对存储多个数据,且数据的类型是没有限制的,所以通常会存储一个商品的信息或一个人的信息: var obj = ...

  5. RV1126 快速启动

    一.硬件信息 RV1126/RV1109 系列芯⽚内置硬件解压缩模块 -- decom,可以极⼤得提升系统启动速度 RV1126/RV1109 内置⼀个 MCU,MCU 在 SoC 上电后就会快速启动 ...

  6. flower插件-监视celery

    安装和使用: https://flower.readthedocs.io/en/latest/install.html#installation https://github.com/mher/flo ...

  7. Collection和Map的区别

    Collection接口,包含list和set子接口Collection和Map接口之间的主要区别在于:Collection中存储了一组对象,而Map存储关键字/值对.在Map对象中,每一个关键字最多 ...

  8. 在k8s中快速搭建基于Prometheus监控系统

    公众号「架构成长指南」,专注于生产实践.云原生.分布式系统.大数据技术分享 前言 K8s本身不包含内置的监控工具,所以市场上有不少这样监控工具来填补这一空白,但是没有一个监控工具有prometheus ...

  9. python异步编程之asyncio初识

    async await介绍 用asyncio提供的@asyncio.coroutine可以把一个生成器标记为协程类型,然后在协程内部用yield from 等待IO操作,让出cpu执行权. 然而异步的 ...

  10. Git和Github库详细使用教程

    SVN 是集中式或者有中心式版本控制系统,版本库是集中放在中央服务器的; Git 是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为 ...