我试图创建一个多线程的骰子滚动模拟 - 只是为了好奇心,多线程编程的喜悦以及向其他人展示“随机结果”的效果(许多人无法理解,如果你连续掷6次掷骰子,你已经有1,2,3,4,5,下一个掷骰子不是6)。为了向他们展示m个骰子的n个卷的分布,我创建了这个代码。c#多任务不能并行运行
那么,结果是好的,但即使我为每个骰子创建一个新的任务程序运行单线程。 多线程将是合理的,以模拟6百万或更多骰子的“数百万”重卷,因为结束时间将快速增长。
我从msdn中读到了几个例子,它们都表明应该有几个同时运行的任务。 有人可以给我一个提示,为什么这段代码不使用很多线程/内核? (甚至没有,当我试图一次运行400个骰子和1000万次重掷)
首先,我初始化存储结果的锯齿状数组。第一维度:每个骰子1个入口,第二个维度将是每个骰子滚动的眼睛分布。
接下来我创建一个任务数组,每个返回结果数组(第二维,如上所述) 每个数组都有6个条目,分别代表laplace W6骰子的每个边。如果骰子掷出1眼,则第一个输入[0]增加+1。因此,您可以查看每个值的滚动频率。
然后我使用一个普通的for-loop来启动所有线程。没有任何迹象表明等到一个线程,直到所有开始。
最后我等待所有人完成并总结结果。它不会有任何区别,如果改变
Task.WaitAll(tasks);到 Task.WhenAll(任务);
我的问题:为什么代码不使用我的CPU的多个核心?我需要改变什么?
提前致谢!
下面的代码:
private void buttonStart_Click(object sender, RoutedEventArgs e)
{
int tries = 1000000;
int numberofdice = 20 ;
int numberofsides = 6; // W6 = 6
var rnd = new Random();
int[][] StoreResult = new int[numberofdice][];
for (int i = 0; i < numberofdice; i++)
{
StoreResult[i] = new int[numberofsides];
}
Task<int[]>[] tasks = new Task<int[]>[numberofdice];
for (int ctr = 0; ctr < numberofdice; ctr++)
{
tasks[ctr] = Task.Run(() =>
{
int newValue = 0;
int[] StoreTemp = new int[numberofsides]; // Array that represents how often each value appeared
for (int i = 1; i <= tries; i++) // how often to roll the dice
{
newValue = rnd.Next(1, numberofsides + 1); // Roll the dice; UpperLimit for random int EXCLUDED from range
StoreTemp[newValue-1] = StoreTemp[newValue-1] + 1; //increases value corresponding to eyes on dice by +1
}
return StoreTemp;
});
StoreResult[ctr] = tasks[ctr].Result; // Summing up the individual results for each dice in an array
}
Task.WaitAll(tasks);
// do something to visualize the results - not important for the question
}
}
当你调用Result时,你会阻塞,直到完成Task任务。 – juharr
尽量让您的解释性文字达到理解和重现问题所需的最低限度。你的问题可能在这一行:'StoreResult [ctr] = tasks [ctr] .Result;'因为['Task.Result'](https://msdn.microsoft.com/en-us/library/dd321468( v = vs.110).aspx):“访问属性的get访问器将阻止调用线程,直到异步操作完成;这相当于调用Wait方法”。解决方法是删除该行,然后在Task.WaitAll()后面迭代结果。 – Quantic
@Quantic: 我不知道,并会给你一个尝试的建议... ------ 宾果! 解决了这个问题! – EinsteinsNierenstein