using System;
using System.Threading;
using System.Threading.Tasks;
// ReSharper disable MemberCanBePrivate.Global
namespace Nullframes.Threading.Tasks
{
///
/// Class contains extension methods for Tasks
///
public static class TaskExtensions
{
#region --- Timeout ---
///
/// Set a timout for the completion of the target . A
/// is thrown if the target task does not complete within the set timeframe.
///
public static async void Timeout(this Task mightTimeout, int timeoutMillisecond, CancellationToken ct = default)
{
await Task.WhenAny(mightTimeout, TimeoutInternalTaskAsync(timeoutMillisecond, ct));
}
///
/// Set a timout for the completion of the target . A
/// is thrown if the target task does not complete within the set timeframe.
///
public static async void Timeout(this Task mightTimeout, TimeSpan timeoutTimeSpan, CancellationToken ct = default)
{
await TimeoutAsync(mightTimeout, timeoutTimeSpan.Milliseconds, ct);
}
//--------------------------------------------------------------------------------------------------------------
///
/// Set a timout for the completion of the target . A
/// is thrown if the target task does not complete within the set timeframe.
///
private static async Task TimeoutInternalTaskAsync(int millisecondsTimeout, CancellationToken ct = default)
{
await Task.Delay(millisecondsTimeout, ct);
throw new TimeoutException($"Timeout after {millisecondsTimeout}ms while awaiting a task!");
}
#endregion
#region --- Timeout Async ---
///
/// Set a timout for the completion of the target . A
/// is thrown if the target task does not complete within the set timeframe.
///
public static Task TimeoutAsync(this Task mightTimeout, int timeoutMillisecond, CancellationToken ct = default)
{
return Task.WhenAny(mightTimeout, TimeoutInternalAsync(timeoutMillisecond, ct));
}
///
/// Set a timout for the completion of the target . A
/// is thrown if the target task does not complete within the set timeframe.
///
public static Task TimeoutAsync(this Task mightTimeout, TimeSpan timeoutTimeSpan, CancellationToken ct = default)
{
return TimeoutAsync(mightTimeout, timeoutTimeSpan.Milliseconds, ct);
}
///
/// Set a timout for the completion of the target . A
/// is thrown if the target task does not complete within the set timeframe.
///
public static async Task TimeoutAsync(this Task mightTimeout, int timeoutMillisecond, CancellationToken ct = default)
{
return await await Task.WhenAny(mightTimeout, TimeoutInternalAsync(timeoutMillisecond, ct));
}
///
/// Set a timout for the completion of the target . A
/// is thrown if the target task does not complete within the set timeframe.
///
public static async Task TimeoutAsync(this Task mightTimeout, TimeSpan timeoutTimeSpan, CancellationToken ct = default)
{
return await TimeoutAsync(mightTimeout, timeoutTimeSpan.Milliseconds, ct);
}
//--------------------------------------------------------------------------------------------------------------
private static async Task TimeoutInternalAsync(int millisecondsTimeout, CancellationToken ct = default)
{
await Task.Delay(millisecondsTimeout, ct);
throw new TimeoutException($"Timeout after {millisecondsTimeout}ms while awaiting a task!");
}
private static async Task TimeoutInternalAsync(int millisecondsTimeout, CancellationToken ct = default)
{
await Task.Delay(millisecondsTimeout, ct);
throw new TimeoutException($"Timeout after {millisecondsTimeout}ms while awaiting a task!");
}
#endregion
//--------------------------------------------------------------------------------------------------------------
#region --- Generic Exception Handling ---
///
/// Ignore any of type Exception that might occur during the execution of the
/// target
///
public static async Task IgnoreExceptionAsync(this Task task) where TException : Exception
{
try
{
await task;
}
catch (TException)
{
}
}
///
/// Ignore every that might occur during the execution of the
/// target
///
public static async Task IgnoreExceptionsAsync(this Task task)
{
try
{
await task;
}
catch (Exception)
{
// ignored
}
}
///
/// Ignore any of type Exception that might occur during the execution of the
/// target . You can set the default value returned by this
/// if an exception occurs.
///
public static async Task IgnoreExceptionAsync(this Task task, TResult defaultValue = default) where TException : Exception
{
try
{
return await task;
}
catch (TException)
{
}
return defaultValue;
}
///
/// Ignore every that might occur during the execution of the
/// target . You can set the default value returned by this
/// if an exception occurs.
///
public static async Task IgnoreExceptionsAsync(this Task task, TResult defaultValue = default)
{
try
{
return await task;
}
catch (Exception)
{
// ignored
}
return defaultValue;
}
#endregion
#region --- Concrete Exception Handling ---
///
/// Ignore any that might occur during the execution of the
/// target
///
public static async Task IgnoreTimeoutException(this Task task)
=> await IgnoreExceptionAsync(task);
///
/// Ignore any that might occur during the execution of the
/// target
///
public static async Task IgnoreOperationCanceledException(this Task task)
=> await IgnoreExceptionAsync(task);
///
/// Ignore any that might occur during the execution of the
/// target
///
public static async Task IgnoreThreadAbortException(this Task task)
=> await IgnoreExceptionAsync(task);
#endregion
#region --- Concrete Exception Handling Async ---
///
/// Ignore any that might occur during the execution of the
/// target . You can set the default value returned by this
/// if an exception occurs.
///
public static async Task IgnoreTimeoutExceptionAsync(this Task task, TResult defaultValue = default)
=> await IgnoreExceptionAsync(task, defaultValue);
///
/// Ignore any that might occur during the execution of the
/// target . You can set the default value returned by this
/// if an exception occurs.
///
public static async Task IgnoreOperationCanceledExceptionAsync(this Task task, TResult defaultValue = default)
=> await IgnoreExceptionAsync(task, defaultValue);
///
/// Ignore any that might occur during the execution of the
/// target . You can set the default value returned by this
/// if an exception occurs.
///
public static async Task IgnoreThreadAbortExceptionAsync(this Task task, TResult defaultValue = default)
=> await IgnoreExceptionAsync(task, defaultValue);
#endregion
}
}