unfifed timeout handling and fixed memory usage due to Task.Delay tasks for each send package are present for the duration of the timeout resulting in memory usage. new approach uses cancellationtoken that will be cleaned up directly if operation completes before timeout

This commit is contained in:
Eggers Jan
2017-09-13 09:12:34 +02:00
parent 5712bc11d2
commit 090e59e99a
5 changed files with 106 additions and 41 deletions
+55
View File
@@ -0,0 +1,55 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Core.Exceptions;
namespace MQTTnet.Core.Internal
{
public static class TaskExtensions
{
public static Task TimeoutAfter( this Task task, TimeSpan timeout )
{
return TimeoutAfter( task.ContinueWith( t => 0 ), timeout );
}
public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan timeout)
{
using (var cancellationTokenSource = new CancellationTokenSource())
{
var tcs = new TaskCompletionSource<TResult>();
cancellationTokenSource.Token.Register(() =>
{
tcs.TrySetCanceled();
} );
try
{
cancellationTokenSource.CancelAfter(timeout);
task.ContinueWith( t =>
{
if (t.IsFaulted)
{
tcs.TrySetException(t.Exception);
}
if (t.IsCompleted)
{
tcs.TrySetResult(t.Result);
}
}, cancellationTokenSource.Token );
return await tcs.Task;
}
catch (TaskCanceledException)
{
throw new MqttCommunicationTimedOutException();
}
catch (Exception e)
{
throw new MqttCommunicationException(e);
}
}
}
}
}