コード例 #1
0
        private async Task Execute()
        {
            var cancelToken = _cancellationTokenSource.Token;

            while (!cancelToken.IsCancellationRequested)
            {
                Activity activity = default;
                try
                {
                    var activeCount = 0;
                    lock (_activeTasks)
                    {
                        activeCount = _activeTasks.Count;
                    }
                    if (activeCount >= MaxConcurrentItems)
                    {
                        await Task.Delay(Options.IdleTime);

                        continue;
                    }

                    activity = WorkflowActivity.StartConsume(Queue);
                    var item = await QueueProvider.DequeueWork(Queue, cancelToken);

                    if (item == null)
                    {
                        activity?.Dispose();
                        if (!QueueProvider.IsDequeueBlocking)
                        {
                            await Task.Delay(Options.IdleTime, cancelToken);
                        }
                        continue;
                    }

                    activity?.EnrichWithDequeuedItem(item);

                    var hasTask = false;
                    lock (_activeTasks)
                    {
                        hasTask = _activeTasks.ContainsKey(item);
                    }
                    if (hasTask)
                    {
                        _secondPasses.Add(item);
                        if (!EnableSecondPasses)
                        {
                            await QueueProvider.QueueWork(item, Queue);
                        }
                        activity?.Dispose();
                        continue;
                    }

                    _secondPasses.TryRemove(item);

                    var waitHandle = new ManualResetEvent(false);
                    lock (_activeTasks)
                    {
                        _activeTasks.Add(item, waitHandle);
                    }
                    var task = ExecuteItem(item, waitHandle, activity);
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, ex.Message);
                    activity?.RecordException(ex);
                }
                finally
                {
                    activity?.Dispose();
                }
            }

            List <EventWaitHandle> toComplete;

            lock (_activeTasks)
            {
                toComplete = _activeTasks.Values.ToList();
            }

            foreach (var handle in toComplete)
            {
                handle.WaitOne();
            }
        }