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#中使用任务。谢谢!
答案 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()不是线程安全的,也不是设计的。