фоновый рабочий процесс задачи c#

Есть ли какие-либо изменения в том, что несколько фоновых рабочих процессов работают лучше, чем задачи, в 5-секундных запущенных процессах? Я помню, как читал в книге, что задача предназначена для кратковременных процессов.

Причина, по которой я спрашиваю, такова:

У меня есть процесс, который занимает 5 секунд, а нужно завершить 4000 процессов. Сначала я сделал:

for (int i=0; i<4000; i++) {
    Task.Factory.StartNewTask(action);
}

и это имело низкую производительность (после первой минуты выполнялось 3-4 задачи, а консольное приложение имело 35 потоков). Может быть, это было глупо, но я думал, что пул потоков справится с такой ситуацией (поставит все действия в очередь, а когда поток освободится, возьмет действие и выполнит его).

Вторым шагом теперь было вручную выполнить фоновые рабочие процессы Environment.ProcessorCount, а все действия поместить в ConcurentQueue. Таким образом, код будет выглядеть примерно так:

var workers = new List<BackgroundWorker>();
//initialize workers

workers.ForEach((bk) =>
{
    bk.DoWork += (s, e) =>
    {
        while (toDoActions.Count > 0)
        {
            Action a;
            if (toDoActions.TryDequeue(out a))
            {
                a();
            }
        } 
    }

    bk.RunWorkerAsync();
});

Это работает намного лучше. Он работал намного лучше, чем задачи, даже когда у меня было 30 фоновых рабочих (столько же задач, как и в первом случае).

ЛЭ:

Я запускаю Задачи так:

    public static Task IndexFile(string file)
    {
        Action<object> indexAction = new Action<object>((f) =>
        {
            Index((string)f);
        });

        return Task.Factory.StartNew(indexAction, file);
    }

И метод Index вот такой:

    private static void Index(string file)
    {
        AudioDetectionServiceReference.AudioDetectionServiceClient client = new AudioDetectionServiceReference.AudioDetectionServiceClient();

        client.IndexCompleted += (s, e) =>
            {
                if (e.Error != null)
                {
                    if (FileError != null)
                    {
                        FileError(client, 
                            new FileIndexErrorEventArgs((string)e.UserState, e.Error));
                    }
                }
                else
                {
                    if (FileIndexed != null)
                    {
                        FileIndexed(client, new FileIndexedEventArgs((string)e.UserState));
                    }
                }
            };

        using (IAudio proxy = new BassProxy())
        {
            List<int> max = new List<int>();
            if (proxy.ReadFFTData(file, out max))
            {
                while (max.Count > 0 && max.First() == 0)
                {
                    max.RemoveAt(0);
                }
                while (max.Count > 0 && max.Last() == 0)
                {
                    max.RemoveAt(max.Count - 1);
                }

                client.IndexAsync(max.ToArray(), file, file);
            }
            else
            {
                throw new CouldNotIndexException(file, "The audio proxy did not return any data for this file.");
            }
        }
    }

Этот метод читает из mp3 файла некоторые данные, используя библиотеку Bass.net. Затем эти данные отправляются в службу WCF с использованием асинхронного метода. Метод IndexFile (строковый файл), который создает задачи, вызывается 4000 раз в цикле for. Эти два события, FileIndexed и FileError, не обрабатываются, поэтому они никогда не выдаются.

6
задан Andrei Neagu 24 May 2012 в 19:51
поделиться