通过生成包含数字的随机任务来添加数字
Add Numbers by generating random tasks containing numbers
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));
}
}
问题是随机数 returns 相同的数字,68 ,68, 122 当它应该 return 不同的数字我做错了什么我正在尝试了解如何在中使用 Task C#。谢谢!
因为您每次都会生成一个新的 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.[=19= 提供的线程安全随机生成器]
看看这里 post:Thread safe random number generation
简而言之:Random() 不是线程安全的,也不是设计成这样的。
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));
}
}
问题是随机数 returns 相同的数字,68 ,68, 122 当它应该 return 不同的数字我做错了什么我正在尝试了解如何在中使用 Task C#。谢谢!
因为您每次都会生成一个新的 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.[=19= 提供的线程安全随机生成器]
看看这里 post:Thread safe random number generation
简而言之:Random() 不是线程安全的,也不是设计成这样的。