首页 > 解决方案 > 当没有字节写入超过给定时间段时如何取消流 CopyToAsync

问题描述

我想检测到 Stream.CopyToAsync 操作停止并检测到超过 1 分钟没有复制字节。

怎么可能做到这一点?

标签: c#.net.net-core

解决方案


您需要定期检查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包括CancellationTokenSourceStreams


推荐阅读