Возвращаемая последовательность чисел оптимизированным, поточно-ориентированным способом - PullRequest
4 голосов
/ 17 февраля 2012

Мне нужен совет по написанию некоторого поточно-оптимизированного, элегантного кода, который бы выполнял следующие действия:

Я хочу, чтобы статический метод возвращал последовательность целых чисел.Так, например, приложение запускается, поток 1 вызывает метод GetSequence и говорит, что хочет получить 3, поэтому он возвращает целочисленный массив, состоящий из 0,1,2.Затем поток 2 вызывает метод и говорит, дайте мне 4, поэтому он возвращает 3,4,5,6.Несколько потоков могут одновременно вызывать этот метод.

Чтобы дать представление о том, о чем я думаю, вот моя попытка:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SequenceNumberService
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] numbers = NumberSequenceService.GetSequence(3);

            foreach (var item in numbers)
            {
                Console.WriteLine(item.ToString());
            }

            // Writes out:
            // 0
            // 1
            // 2

            Console.ReadLine();
        }
    }

    public static class NumberSequenceService
    {
        private static int m_LastNumber;
        private static object m_Lock = new Object();

        public static int[] GetSequence(int take)
        {
            int[] returnVal = new int[take];
            int lastNumber;

            // Increment the last audit number, based on the take value.
            // It is here where I am concerned that there is a threading issue, as multiple threads
            // may hit these lines of code at the same time.  Should I just put a lock around these two lines
            // of code, or is there a nicer way to achieve this.
            lock (m_Lock)
            {
                m_LastNumber = m_LastNumber + take;
                lastNumber = m_LastNumber;
            }

            for (int i = take; i > 0; i--)
            {
                returnVal[take - i] = lastNumber - i;
            }

            return returnVal;
        }
    }
}

Поэтому мои вопросы: AmЯ подхожу к этому наилучшим образом, или есть другой способ добиться этого?Любые предложения по оптимизации этого кода?

Большое спасибо заранее за любую помощь.

1 Ответ

7 голосов
/ 17 февраля 2012

Возможно, вы захотите взглянуть на класс Interlocked , и он увеличивает и добавляет методы:

public static Int32 num = 0;

public static Int32 GetSequence() 
{ 
    return Interlocked.Increment(ref num); 
}

public static IEnumerable<Int32> GetSequenceRange(Int32 count) 
{ 
    var newValue = Interlocked.Add(ref num, count);
    return Enumerable.Range(newValue - count, count);
}
...