Esempio n. 1
0
        public async Task StartAsync()
        {
            // ReSharper disable once MethodSupportsCancellation
            await runningInstanceSemaphore.WaitAsync();

            try
            {
                if (runningInstance != null)
                {
                    return;
                }

                runningInstance = new AsyncTimerStartedInstance(cancellationToken);
#pragma warning disable 4014 // Don't await, just schedule in background
                // ReSharper disable once MethodSupportsCancellation
                Task.Run(() => MainLoopAsync(runningInstance));
#pragma warning restore 4014
            }
            finally
            {
                runningInstanceSemaphore.Release();
            }
        }
Esempio n. 2
0
        private async Task MainLoopAsync([NotNull] AsyncTimerStartedInstance currentInstance)
        {
            if (currentInstance == null)
            {
                throw new ArgumentNullException(nameof(currentInstance));
            }
            try
            {
                currentInstance.CancellationToken.ThrowIfCancellationRequested();

                await Task.Delay(initialDelay, currentInstance.CancellationToken);

                do
                {
                    currentInstance.CancellationToken.ThrowIfCancellationRequested();

                    var actions = Elapsed
                                  ?.GetInvocationList()
                                  .ToArray()
                                  .Cast <AsyncTimerActionDelegate>();

                    if (actions == null)
                    {
                        continue;
                    }

                    var cancellationTokenCopy = currentInstance.CancellationToken;
                    await Task.WhenAll(actions.Select(async action =>
                    {
                        try
                        {
                            await action(cancellationTokenCopy);
                        }
                        catch (Exception exception)
                        {
                            try
                            {
                                var task = ExceptionOccurred?.Invoke(action, exception);
                                if (task != null)
                                {
                                    await task;
                                }
                            }
                            catch { /* ignored */ }
                        }
                    }));

                    currentInstance.CancellationToken.ThrowIfCancellationRequested();

                    await Task.Delay(interval, currentInstance.CancellationToken);
                }while (autoReset);
            }
            catch (TaskCanceledException) { /* expected */ }
            finally
            {
                // ReSharper disable once MethodSupportsCancellation
                await runningInstanceSemaphore.WaitAsync();

                try
                {
                    if (runningInstance == currentInstance)
                    {
                        runningInstance = null;
                    }
                }
                finally
                {
                    runningInstanceSemaphore.Release();
                }

                try { currentInstance.Dispose(); } catch { /* ignored */ }
            }
        }