c# - 当没有字节写入超过给定时间段时如何取消流 CopyToAsync
问题描述
我想检测到 Stream.CopyToAsync 操作停止并检测到超过 1 分钟没有复制字节。
怎么可能做到这一点?
解决方案
您需要定期检查Stream.Length
,如果没有进展,请取消使用CancellationTokenSource
。这是基本上使用计时器定期检查复制是否有任何进展的代码。
using System.IO;
using System.Threading;
using System.Threading.Tasks;
var copyingCompleted = false;
var copyBufferSize = 4096;
var interval = (int)TimeSpan.FromMinutes(1).TotalMilliseconds;
var initialTimeoutMilliseconds = -1;//inifinite
var timer = new Timer(OnTimerElapsed,null,initialTimeoutMilliseconds,interval);
var cts = new CancellationTokenSource();
long streamLength = 0;
Stream srcStream = null;//should be your sourceStream
Stream dstStream = null;//should be your destination stream
await Copy(srcStream,dstStream,cts.Token);
public async Task Copy(Stream src,Stream dst, CancellationToken cancellationToken){
timer.Change(interval,interval);
try{
await src.CopyToAsync(dst,copyBufferSize, cancellationToken);
}
finally{
copyingCompleted = true;
}
}
public void OnTimerElapsed(object state){
if(copyingCompleted){
//stop the timer
timer.Change(-1,-1);
return;
}
//check if the copying has progressed since the last interval callback was invoked
if(dstStream.Length > streamLength){
//copy has progressed, I will check you in the next interval
streamLength = dstStream.Length;
return;
}
//you didn't make any progress, I am cancelling the copy process
cts.Cancel();
}
这不是完整的实现,您需要处理一次性资源,Timer
包括CancellationTokenSource
和Stream
s
推荐阅读
- java - 无法加载配置 application.properties
- python - 我想在 ibm cloud 中创建一个具有公共访问权限的存储桶。任何人都应该能够访问它?
- microservices - QLDB 是否与发件箱模式兼容?
- algorithm - 修改的最小生成树
- eventhandler - 无后端事件处理程序
- javascript - 如何消除 JavaScript 中的重复元素(包括自身)?
- yaml - yaml 中的云形成模板如何检查导出的堆栈是否存在(使用嵌套?堆栈)
- reactjs - 反应服务器端数据表
- azure - 无法将文件从 ADLS 移动到雪花
- php - 如何在 PHP 中替换 JSON 上的匹配对象?