예제 #1
0
        public static async Task Worker(FunctionToGetWorkItem getWorkItem, Action <Exception> callOnException, int maxParallel)
        {
            Task[] tasksInProgress    = new Task[maxParallel];
            int    numTasksInProgress = 0;

            while (true)
            {
                Task newTask;
                if (!getWorkItem(out newTask))
                {
                    // There are no more tasks to perform.  Wait until the last one is completed.
                    if (numTasksInProgress > 0)
                    {
                        await Task.WhenAll(tasksInProgress.Take(numTasksInProgress));
                    }
                    return;
                }
                if (newTask.IsCompleted || newTask.IsCanceled)
                {
                    continue;
                }
                if (newTask.IsFaulted)
                {
                    callOnException(newTask.Exception);
                    continue;
                }

                // The task could not complete immediately, is still in progress, and needs to be awaited...
                if (numTasksInProgress > 0)
                {
                    RemoveCompletedTasks(tasksInProgress, ref numTasksInProgress, callOnException);

                    if (numTasksInProgress >= tasksInProgress.Length)
                    {
                        await Task.WhenAny(tasksInProgress);

                        RemoveCompletedTasks(tasksInProgress, ref numTasksInProgress, callOnException);
                    }
                }

                // Now add the new task
                tasksInProgress[numTasksInProgress++] = newTask;
            }
        }
예제 #2
0
        public static async Task Worker(FunctionToGetWorkItem getWorkItem, Action <Exception> callOnException, int maxParallel)
        {
            Task[] tasksInProgress    = new Task[maxParallel];
            int    numTasksInProgress = 0;

            while (true)
            {
                Task newTask;
                if (!getWorkItem(out newTask))
                {
                    if (numTasksInProgress > 0)
                    {
                        await Task.WhenAll(tasksInProgress.Take(numTasksInProgress));
                    }
                    return;
                }
                if (newTask.IsCompleted || newTask.IsCanceled)
                {
                    continue;
                }
                if (newTask.IsFaulted)
                {
                    callOnException(newTask.Exception);
                    continue;
                }

                if (numTasksInProgress > 0)
                {
                    RemoveCompletedTasks(tasksInProgress, ref numTasksInProgress, callOnException);

                    if (numTasksInProgress >= tasksInProgress.Length)
                    {
                        await Task.WhenAny(tasksInProgress);

                        RemoveCompletedTasks(tasksInProgress, ref numTasksInProgress, callOnException);
                    }
                }

                tasksInProgress[numTasksInProgress++] = newTask;
            }
        }