Attempt at making the connection more robust

This commit is contained in:
Mark van Renswoude 2020-08-13 11:24:17 +02:00
parent 5e0513fc81
commit d998b65a9c

View File

@ -29,7 +29,7 @@ namespace IPCamAppBar
private readonly CancellationTokenSource cancelTaskTokenSource = new CancellationTokenSource(); private readonly CancellationTokenSource cancelTaskTokenSource = new CancellationTokenSource();
private Task streamTask; private Task streamTask;
private DataMonitor dataMonitor;
protected CameraStream() protected CameraStream()
{ {
@ -89,12 +89,24 @@ namespace IPCamAppBar
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
} }
if (response.StatusCode != HttpStatusCode.OK) if (response.StatusCode != HttpStatusCode.OK)
throw new WebException(response.StatusDescription); throw new WebException(response.StatusDescription);
using (var responseStream = response.GetResponseStream()) using (var responseStream = response.GetResponseStream())
{ {
await ReadFrames(responseStream, cancellationToken); var dataMonitorCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
dataMonitor = new DataMonitor(dataMonitorCancellationTokenSource, TimeSpan.FromSeconds(15));
try
{
await ReadFrames(responseStream, dataMonitorCancellationTokenSource.Token);
}
catch (TaskCanceledException)
{
if (!dataMonitorCancellationTokenSource.IsCancellationRequested)
throw;
}
} }
} }
catch (TaskCanceledException) catch (TaskCanceledException)
@ -121,6 +133,7 @@ namespace IPCamAppBar
protected virtual void OnFrame(FrameEventArgs args) protected virtual void OnFrame(FrameEventArgs args)
{ {
dataMonitor.Reset();
Frame?.Invoke(this, args); Frame?.Invoke(this, args);
} }
@ -156,6 +169,35 @@ namespace IPCamAppBar
return -1; return -1;
} }
}
internal class DataMonitor
{
private readonly CancellationTokenSource cancellationTokenSource;
private readonly long timeout;
private readonly Timer timeoutTimer;
public DataMonitor(CancellationTokenSource cancellationTokenSource, TimeSpan timeout)
{
this.cancellationTokenSource = cancellationTokenSource;
this.timeout = (long)timeout.TotalMilliseconds;
timeoutTimer = new Timer(Tick, null, this.timeout, -1);
}
public void Reset()
{
timeoutTimer.Change(timeout, -1);
}
private void Tick(object state)
{
cancellationTokenSource.Cancel();
}
} }
} }