I'd like to detect that Stream.CopyToAsync operation stalls and detect that when for longer than 1 minute no bytes are copied.
How that could be done?
I'd like to detect that Stream.CopyToAsync operation stalls and detect that when for longer than 1 minute no bytes are copied.
How that could be done?
You need to periodically check the Stream.Length, If the there is no progress, cancel the using CancellationTokenSource. Here is the code which basically uses the timer to periodically check if there is any progress with copying.
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();
}
This is not the complete implementation, you need to take care of disposing the disposable resources, including Timer, CancellationTokenSource and Streams
You need to use the overload of CopyToAsync that takes a cancellation token.
How to do it is explained here: Cancel async tasks after a period of time