在 dotnet 6 里,推荐的网络通讯是使用 的超时机制
在 秒内如果文件还没上传完成,也就是网络活动还没完成,将会触发超时异常
这是比较非预期的逻辑,大部分情况下,在国内的弱网环境下,可能在上传过程中,网络几乎被断开,网络几乎被断开等同于上传速度非常慢imtoken。整个文件上传过程可以分为两个阶段,第一个阶段和服务器建立连接的过程,这个过程如果采用 属性作为超时时间,那是比较合理的。第二个阶段是上传数据过程,这个过程的时间完全和上传的数据量相关。显然,如果将第二个阶段也计算入超时时间范围内,是不符合预期的
在使用 。而对于上传文件的情况,这是不符合预期的逻辑,更多的时候,需要的是,如果上传的速度慢到一定程度的时候,报告超时给到业务端。例如上传的速度很长时间就几乎为零,那就应该报给上层业务端
但文件上传过程如上文,可以分为两个阶段imtoken。可以通过更底层控制的方法设置 的和服务器连接的超时时间,代码如下
varsockets
ConnectTimeout=TimeSpan.FromSeconds(20),
var)
Timeout=TimeSpan.FromSeconds(100)
在 有什么差别
展开全文
有些伙伴在遇到此问题的时候,在网上搜到了一些上古的解决方案,那就是采用 文件将占用大量内存
一个实现机制也如官方所说,如果要对上传逻辑有足够的控制,那请用好 PostAsync 最后一个参数,也就是说一个好的方式是将 的取消参数控制
实现方法是先将 属性设置为无穷时间超时,然后靠取消参数控制超时
varsockets
ConnectTimeout=TimeSpan.FromSeconds(20),
var)
Timeout=Timeout.InfiniteTimeSpan
接下来再定义一个 Upload 类型,用来做实际上的上传速度控制逻辑
classUpload{}
需要传入实际上文件上传数据的 ,和设置的超时时间
privateTimeSpan _timeout;
privatereadonly ;
这里的超时时间定义不是上传的总时间,而是上传过程中网络断开的时间imtoken。这里的网络断开是等同于网络速度足够慢,例如定义为经过了 100 秒还上传不了 1 MB 的数据,那就上报超时
先忽略 Upload,先看一下使用的方法
先获取到一个上传的数据imtoken,以下采用一个测试用的 Stream 代替
varstreamContent=newStreamContent(newFakeStream(1024_0000_0000));
这里的 FakeStream 可以产生如参数传给他的数据量imtoken,可以看到这是一个比较大的数据
再定义取消的参数
varcancellationTokenSource=newCancellationTokenSource;
接着创建 Upload 对象
varupload);
将 Upload,代码如下
varresult=await);
在 Upload。每次进入方法可以记录间隔时间,从而实现通过间隔时间判断上传超时
classUpload;
StartDog;
while((count = _stream.Read(buffer, 0, buffer.Length)) > 0) {// 这里存在一个问题是如果先读取完成了缓存imtoken,然后发送慢了,依然会炸掉_stopwatch.Restart;
awaitstream.WriteAsync( newReadOnlyMemory< byte>(buffer, 0, count), _tokenSource.Token); }}
privatereadonlyStopwatch _stopwatch = newStopwatch;}
在进入 SerializeToStreamAsync 方法时,也就是开始发起请求时,将开启 StartDog 方法imtoken。进入 SerializeToStreamAsync 方法是不需要等待和服务器连接开始就调用的,因为在底层调用 SerializeToStreamAsync 方法是先将数据读取到缓存里面,在建立连接完成之后,将从缓存里面发送数据给服务器。这样的设计的原因是为了提升性能,如果是在连接完成之后再进行读取 SerializeToStreamAsync 方法,那将会导致连接完成之后需要等待一下才能从业务端读取到数据
在进入第一次读取调用 StartDog 将进入一个循环逻辑,在这里面判断 _stopwatch 字段,从而了解到调用的频率imtoken。此读取的频率约等于网络上传的速率,但是需要了解的是输入参数的 stream 是本地的缓存。在本地缓慢满的时候,调用 WriteAsync 方法将不会返回
privateasyncvoidStartDog( ) {while(!_isFinished) {awaitTask.Delay(_timeout / 2); if(_isFinished) {return; }
if(_stopwatch.Elapsed > _timeout) {_tokenSource.Cancel;return; }}}
privatebool_isFinished;
publicvoidSetIsFinished( ) => _isFinished = true;
在 StartDog 里面大概等待时间间隔是 _timeout / 2 的值,在这个范围内判断是否有 _stopwatch 距离上次开启的时间超过 _timeout 的值,如果超过了,那就证明网络速度足够慢imtoken。这里的等待间隔选用 _timeout / 2 的值,最差等待超时时间将会是实际超时的 1.5 倍时间,如果关心超时时间,那请将这个间隔设置比较小
以上代码的 SetIsFinished 是设计给上传完全完成之后调用的imtoken,如果不调用问题也不大,因此最后也会判断超时而返回,只是这个最后判断设置的逻辑是没有实际使用的
varupload;// 设置完成
如果去掉以上的 SetIsFinished 方法,修改为在 SerializeToStreamAsync 方法调用结束的时候设置 _isFinished 的值,那存在一个小问题,那就是进入 SerializeToStreamAsync 方法的循环最后一次是将数据写入到缓存里面,假设网络速度在发送最后的缓存数据是比较慢的,那无疑没有后续的判断逻辑可以告诉超时时间imtoken。为了解决此问题,才有了 SetIsFinished 方法,在实际上的 Post 完成之后,再进行设置。当然了此时不设置问题也不大,只是多了一次无效的超时调用
接下来写一点测试代码imtoken,在服务器端设置了上传将会是一个缓慢读取的方式,如下面代码
usingSystem.Buffers;WebApplicationBuilder builder = WebApplication.CreateBuilder(args);builder.WebHost.UseUrls( ");
intcount; while((count = awaitcontext.Request.Body.ReadAsync(buffer, 0, length)) > 0) {awaitTask.Delay( 1000); }
ArrayPool< byte>.Shared.Return(buffer);
context.Response.StatusCode = StatusCodes.Status200OK;awaitcontext.Response.WriteAsync( "Hello World!");});app.Run;
以上的服务器端的接收客户端上传的速度是可以接受的imtoken,每次读取都等待一秒的时间,这比设置的超时时间短,因此调用 Upload 上传是不会超时的
再写另一个服务器端的方法imtoken,这个方法接收数据会更加慢,比设置的超时时间慢
app.MapPost( "/UploadTimeout", asynccontext =>{ varlength = 1024* 1024* 100; varbuffer = ArrayPool< byte>.Shared.Rent(length);
intcount; intn = 0; while((count = awaitcontext.Request.Body.ReadAsync(buffer, 0, length)) > 0) {awaitTask.Delay( 1000); n++;if(n == 10) {awaitTask.Delay(TimeSpan.FromHours( 10)); }}
ArrayPool< byte>.Shared.Return(buffer);
context.Response.StatusCode = StatusCodes.Status200OK;awaitcontext.Response.WriteAsync( "Hello World!");})
此时的客户端上传将会被提示超时
以上逻辑即可实现让客户端上传大量数据时imtoken,通过上传的速度设置超时,可以比较好解决国内的弱网环境
以上的代码放在github 和 gitee 欢迎访问
可以通过如下方式获取本文的源代码imtoken,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin
git pull origin 3015fafa0a38e1eb98b0b7eed117f46911253ea4
以上使用的是 gitee 的源imtoken,如果 gitee 不能访问,请替换为 github 的源
git remote remove origin
git remote add origin
获取代码之后imtoken,进入 NekejawcharlereJibabearcel 文件夹
但是 设置的时间,依然能继续下载
测试下载超时的影响的代码imtoken,在服务端添加如下代码,用来提供一个非常大的数据给客户端下载
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);builder.WebHost.UseUrls( ");
for( inti = 0; i < 1000000; i++) {awaitcontext.Response.Body.WriteAsync( newReadOnlyMemory< byte>(buffer));
if(i < 10) {awaitTask.Delay(TimeSpan.FromSeconds( 1)); }else{awaitTask.Delay(TimeSpan.FromMinutes( 1)); }}});app.Run;
客户端设置超时 10 秒imtoken,然后进行下载,以下代码一定是 10 秒下载不完成的
asyncTask Download( ) { var) };
varstream = await");
varcount = 0; varbuffer = ArrayPool< byte>.Shared.Rent( 1024* 1024); while((count = stream.Read(buffer.AsSpan)) > 0) {Console.WriteLine( $" {count}" ); }}
可以看到下载超过了 10 秒还能继续下载imtoken,证明了 Timeout 属性对下载是无效的
原文:
版权声明:本文来源于网友收集或网友提供,仅供学习交流之用,如果有侵权,请转告版主或者留言,本公众号立即删除imtoken。
支持小薇
领腾讯云618福利红包 :
618抢先购 爆款2核2G4M 40GSSD云服务器劲爆45元imtoken,更多浏览
链接:
关注: DotNet开发跳槽
觉得不错imtoken,请点个在看 呀
阳光和暖huobi,微风徐来 从繁华的街市到乡村美景 空港(硕放)总有许多理由让人爱上ta 作为硕放人 “SHUOFANG”就成为huobi了 大家心中骄傲而永恒的字符 小编就用这8个字母组成的关键词 解锁 硕放的方方面面 带huobi你重新认识 硕放...
作者:冉伟 在过去几年中,区块链技术在各国政务、金融,以及其它各行业中的应用效果不断得到验证,一个新兴的区块链应用市场随之发展壮大起来区块链。作为区块链应用生态的底座,区块链基础设施(简称“区块链设施”)的重要性也日渐凸显。 在此背景下,越来越多的国家投入到区块链设施的开发、建设与应用热潮之中,并直...
7月14日,中国信息通信研究院公布腾讯区块链通过了第七批“可信区块链评测”全部评测项目区块链。据悉,腾讯区块链是本批唯一一家在区块链平台功能评测、区块链安全评测中通过全部评测项的厂商,这也是腾讯区块链TrustSQL的新引擎V2首次参与评测。信通院是在“2022可信区块链生态大会暨首届信任科技大会”...
5月3日消息: 美股三大指数集体收涨,纳指涨1.63%,标普500指数涨0.57%,道指涨0.26%比特币。 阿根廷最大私人银行Banco Galicia推出加密货币交易功能 美国十年期国债收益率上破3%,为2018年12月以来首次比特币。 消息人士称,花旗集团执行了一笔错误的交...
市场总是给人太多惊喜btc。7月20日,美股三大指数集体收涨,道指涨2.42%,标普500指数涨2.75%,纳指涨3.11%。在市场情绪联动下,BTC也顺势突破阻力位23000,加密市场总市值已升至1.1万亿美元,24小时涨幅4.6%。 尽管突破重要阻力位,但从市场情绪指数看,仅仅上升了一个点位,从...
开发项目最重要的是追求质量能过关,在开发系统领域中,很多项目都是有数量没质量的,专门坑骗一些不知情的企业nft。NFT开发在当前颇有名气,我们可以在哪些方面,来提高NFT开发的质量。 本文章由小编【Hanquankeji】整理发布nft,未经允许禁止转载搬运! 一、找专业的NFT开发公司 做NFT开...