通过生成包含数字

时间:2015-05-13 14:15:30

标签: c# task-parallel-library

public TestClass{

     public  Task<int> GetRandomNumber() {
                return Task.FromResult(new Random().Next(0, 1500));
            }
    }



public class Default
    {
        static void Main(string[] args)
        {
            var test = new TestClass();
            List<int> adddata = new List<int>();
            for (int i = 0; i < 3; i++)
            {
              var  result = Task.Run(() => test.GetRandomNumber());
              Console.WriteLine("The values that will be added are :{0}", result.Result);
              adddata.Add(result.Result);    
            }
            Console.WriteLine("The value is :{0}", adddata.Sum(v => v));
     }
}

问题是随机数返回相同的数字,68,68,122当它应该返回不同的数字我做错了什么我试图学习如何在C#中使用任务。谢谢!

2 个答案:

答案 0 :(得分:4)

因为您每次都会生成一个新的Random实例。创建一次Random对象。由于Random不是线程安全的,我们需要使用随机生成器:

public static class ThreadSafeRandom 
{ 
    private static Random global = new Random(); 

    [ThreadStatic] 
    private static Random local;

    public static int Next() 
    { 
        Random inst = local; 
        if (inst == null) 
        { 
            int seed; 
            lock (global) 
            {
                seed = global.Next(); 
            }

            local = inst = new Random(seed); 
        } 

        return inst.Next(); 
    } 
}

现在消耗它:

public TestClass
{
     public Task<int> GetRandomNumber() 
     {
         return Task.FromResult(ThreadSafeRandom.Next());
     }
}

修改

作为旁注,您正在线程池线程上执行您的委托,并立即使用Result同步阻止它。我假设你要做的是并行执行:

static void Main(string[] args)
{
    var test = new TestClass();

    Task<int>[] addData = Enumerable.Range(0, 4)
                                    .Select(_ => Task.Run(() => test.GetRandomNumber()))
                                    .ToArray();

    Task.WaitAll(addData);
    foreach (var result in addData)
    {
        Console.WriteLine("The values that will be added are :{0}", result.Result);
    }

    Console.WriteLine("The value is :{0}", adddata.Select(x => x.Result).Sum());
}

编辑2:

根据@ChrisL正确指出Random不是线程安全的,我修改了代码以使用the PFX team提供的线程安全随机生成器。

答案 1 :(得分:0)

点击这里的帖子:Thread safe random number generation

简而言之:Random()不是线程安全的,也不是设计的。