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. 递归+DP:爬楼梯问题

        一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级.求该青蛙跳上一个n 级的台阶总共有多少种跳法. 输入格式: 首先输入数字n,代表接下来有n组输入,50>=n>=0,然后每行一个 ...

  2. (Good topic)四因数 (leetcode 181周赛T2)

     四因数难度中等1收藏分享切换为英文关注反馈给你一个整数数组 nums,请你返回该数组中恰有四个因数的这些整数的各因数之和. 如果数组中不存在满足题意的整数,则返回 0 .   示例: 输入:nums ...

  3. offline RL | TD3+BC:在最大化 Q advantage 时添加 BC loss 的极简算法

    题目:A Minimalist Approach to Offline Reinforcement Learning ,NeurIPS 2021,8 7 7 5. pdf 版本:https://arx ...

  4. list.add()语句作用

    ----该方法用于向集合列表中添加对象 示例  本示例使用List接口的实现类ArrayList初始化一个列表对象,然后调用add方法向该列表中添加数据. public static void mai ...

  5. ij社区版如何创建spring项目

    他们说是使用spring  init什么什么的,那个都是老版的名称了,你去插件里面搜找是肯定搜不到的,现在叫spring boot helper,用这个,安装一下就好了(注意本次是在2022/11/1 ...

  6. [ABC261Ex] Game on Graph

    Problem Statement We have a directed graph with \(N\) vertices and \(M\) edges. Edge \(i\) is direct ...

  7. RDBMS与Hbase对比 HDFS与HBase对比 Hive与HBase对比

    RDBMS: HBASE: HDFS与HBase对比: Hive与HBase对比: Hive与HBase总结

  8. 简单介绍JDK、JRE、JVM三者区别

    简单介绍JDK vs JRE vs JVM三者区别 文编|JavaBuild 哈喽,大家好呀!我是JavaBuild,以后可以喊我鸟哥,嘿嘿!俺滴座右铭是不在沉默中爆发,就在沉默中灭亡,一起加油学习, ...

  9. 如何使用 Helm 在 K8s 上集成 Prometheus 和 Grafana|Part 2

    在 Part 1 中,我们一起了解了什么是 Prometheus 和 Grafana,以及使用这些工具的前提条件和优势.在本部分,将继续带您学习如何安装 Helm 以及如何使用 Prometheus ...

  10. 文心一言 VS 讯飞星火 VS chatgpt (30)-- 算法导论5.2 2题

    二.在 HIRE-ASSISTANT 中,假设应聘者以随机顺序出现,你正好雇用两次的概率是多少? 文心一言: 我们可以先计算出在HIRE-ASSISTANT中,雇佣一个应聘者的概率为3/4,然后计算出 ...