给出以下问题:从键盘输入组装玩具的机器人数量和要组装的套件数量。玩具组装套件的数量必须至少是机器人数量的100倍。每个机器人在一定时间内组装一个玩具,落在用户从键盘输入的范围内(用随机数替换)。一旦玩具组装完毕,机器人就会拿出一套新的套件来组装玩具,直到所有套件都组装完毕。每个机器人在单独的线程中工作。在 WinForms 中工作。
为此,创建了此代码:
public bool stop;
List<Thread> threads = new List<Thread>();
int[] robots;
int numberSets = 0;
Random random = new Random();
object locker = new object();
private void button1_Click(object sender, EventArgs e)
{
if (Convert.ToInt32(numberRobots.Text) * 100 <= Convert.ToInt32(numberSet.Text))
{
robots = new int[Convert.ToInt32(numberRobots.Text)];
for (int i = 0; i < Convert.ToInt32(numberRobots.Text); i++)
{
robots[i] = i + 1;
}
for (int i = 0; i < Convert.ToInt32(numberRobots.Text); i++)
{
threads.Add(new Thread(new ParameterizedThreadStart(CreatSet)));
threads[i].Name = $"Робот {i + 1}";
threads[i].Start(Convert.ToInt32(robots[i]));
}
}
else
{
Console.WriteLine("Неправильно!");
}
}
public void CreatSet(object obj)
{
int numberRobot = (int)obj;
while (numberSets != Convert.ToInt32(numberSet.Text))
{
int tsb = random.Next(50, 100);
numberSets++;
lock (locker)
{
var message = $"• {Thread.CurrentThread.Name} начал сбор набора №{numberSets}. Время сбора набора: {tsb} секунд;";
Invoke((MethodInvoker)delegate
{
infAssembly.Items.Add(message);
});
}
var message1 = $"• {Thread.CurrentThread.Name} закончил сбор набора №{numberSets}.";
Thread.Sleep(tsb);
Invoke((MethodInvoker)delegate { infAssembly.Items.Add(message1); });
//Thread.Sleep(random.Next(50, 100));
}
var message2 = $"• Наборы для сборки закончились.";
Invoke((MethodInvoker)delegate { infAssembly.Items.Add(message2); });
}
它似乎可以工作,但是它产生了这样的无意义的结果,即第一个具有同样构建时间的流就完成了。治疗方法是去除lock。但随之而来的是,lock出于某种原因,这是老师要求该程序需要的功能,这与“机器人必须并行工作”这一陈述的逻辑相悖。简而言之,我如何重写程序以使其存在lock,同时它们可以并行工作?
意见和建议:
robots目前还不清楚为什么需要这个数组。它的i第个元素仅仅等于i+1,不需要将该值存储在任何地方。threads。您需要以完全相同的方式浏览此列表并对Join()每个流执行此操作。robots流使用数组。假设您以几乎相同的方式使用它们 - 通过索引进行访问,并具有预先知道的元素数量。这再次表明您不知道集合的用途,并且随机使用它们。Invoke(更改元素UI),您将始终处于主线程中UI。UI并转换值Convert.ToInt32(numberSet.Text),最好在按下按钮后立即执行此转换,并将结果放入然后在循环中使用的变量中。numberSets局部变量中更改的值,以便您可以以其当前形式输出它,而不会被其他线程更改。再说一遍,这样您就不必将它包装在lock一堆没有它也能正常工作的代码中。很多不必要的东西:
robots——你不需要它threads——你不需要它这是我的版本
始终追求代码的简单性。如果您不确定是否需要某个数组,请不要创建它。对重复的代码片段使用单独的方法。使用变量避免重复相同的操作。