2012-02-16 64 views
4

我正在寻找一些建议上写了一些线程安全的,优化返回数字序列,优雅的代码执行以下操作:在优化,线程安全的方式

我想一个静态方法来返回整数序列。因此,例如,应用程序启动,线程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; 
     } 
    } 
} 

我的问题是: 我是不是接近这一以最好的方式,还是有另一种方式来实现这一点? 有关优化此代码的任何建议?

非常感谢您的任何帮助。

+0

我觉得你的方法看起来相当不错。 – dana 2012-02-16 21:42:36

回答

6

你可能要考虑的Interlocked类和它的IncrementAdd方法:

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); 
} 
+2

如果两个线程同时要求3个数字,则可能会返回{0,2,4}和{1,3,5}。我认为这个问题要求每个序列都是连续的。 – 2012-02-16 21:40:56

+0

已修复,谢谢@RogerLipscombe – 2012-02-16 21:41:11

+0

某些地方的线程可以解决下一个数字,然后使用Interlocked.CompareExchange“保留”该范围应该做的伎俩... – 2012-02-16 21:42:37