using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Tango.Core.Threading { /// /// Represents a task that will be awaited for a limited time. /// If the timeout has reached, the task will return and will continue in the background. /// public class LimitedTimeTask { private Action _action; private TimeSpan _timeout; private bool _completed; public LimitedTimeTask(Action action, TimeSpan timeout) { _action = action; _timeout = timeout; } public Task Run() { TaskCompletionSource completion = new TaskCompletionSource(); ThreadFactory.StartNew(() => { try { _action?.Invoke(); if (!_completed) { _completed = true; try { completion.SetResult(true); } catch { } } } catch (Exception ex) { if (!_completed) { _completed = true; try { completion.SetException(ex); } catch { } } } }); TimeoutTask.StartNew(() => { if (!_completed) { _completed = true; try { completion.SetException(new TimeoutException($"The limited time task did not complete within the given time of {(int)_timeout.TotalMilliseconds} milliseconds and will continue in the background if possible.")); } catch { } } }, _timeout); return completion.Task; } public static Task StartNew(Action action, TimeSpan timeout) { return new LimitedTimeTask(action, timeout).Run(); } } }