2019-04-29 15:42:09 +00:00
|
|
|
using System;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
2021-08-27 15:03:47 +00:00
|
|
|
namespace PluralKit.Core
|
|
|
|
{
|
|
|
|
public static class TaskUtils
|
|
|
|
{
|
|
|
|
public static async Task CatchException(this Task task, Action<Exception> handler)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2019-04-29 15:42:09 +00:00
|
|
|
await task;
|
2021-08-27 15:03:47 +00:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2019-04-29 15:42:09 +00:00
|
|
|
handler(e);
|
|
|
|
}
|
|
|
|
}
|
2021-08-27 15:03:47 +00:00
|
|
|
|
|
|
|
public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan? timeout)
|
|
|
|
{
|
2019-04-29 15:42:09 +00:00
|
|
|
// https://stackoverflow.com/a/22078975
|
2021-08-27 15:03:47 +00:00
|
|
|
using (var timeoutCancellationTokenSource = new CancellationTokenSource())
|
|
|
|
{
|
2019-04-29 15:42:09 +00:00
|
|
|
var completedTask = await Task.WhenAny(task, Task.Delay(timeout ?? TimeSpan.FromMilliseconds(-1), timeoutCancellationTokenSource.Token));
|
2021-08-27 15:03:47 +00:00
|
|
|
if (completedTask == task)
|
|
|
|
{
|
2019-04-29 15:42:09 +00:00
|
|
|
timeoutCancellationTokenSource.Cancel();
|
|
|
|
return await task; // Very important in order to propagate exceptions
|
2021-08-27 15:03:47 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-04-29 15:42:09 +00:00
|
|
|
throw new TimeoutException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|