【发布时间】:2015-07-12 08:33:39
【问题描述】:
假设我有这段特定的代码:
/****************************************************************/
/* Generate new wave of enrollees */
/****************************************************************/
for (int i = 1; i <= new Random().Next(enrolleesExpectedPerMinuteMin, enrolleesExpectedPerMinuteMax) && enrolleesInCampus < enrolleesExpectedTotal; i++)
{
Enrollee newEnrollee = new Enrollee("ENRL" + i, i);
listOfEnrollees.Add(newEnrollee);
enrolleesInCampus = listOfEnrollees.Count;
lblEnrolleesInCampusNum.Text = enrolleesInCampus.ToString();
newEnrollee.enroll(listOfOffices);
}
请注意,它在 GUI 计时器的 tick 方法上运行。看,我正在生成 Enrollee 对象。他们有一个名为enroll() 的函数,它接受一个参数,这是一个Enrollee 可以访问的所有Office 对象的列表。
每个Office 对象都有一个ServiceLane 对象列表。这些ServiceLane 对象有一个Enrollees 的队列;还有,称为enqueue() 和dequeue() 的方法。 enqueue() 只接受Enrollee 类型的参数并将其添加到enrolleesInLine 列表中,该列表表示Enrollee 对象在ServiceLane 对象上排队。 dequeue() 方法当然会执行出队,但我需要它在 ServiceLane 所需的特定处理时间后执行出队。
ServiceLanes 和 Enrollee 的去向取决于 Enrollee 的类型和他们需要进入的当前 Office,因此,我构造了这样的 enroll() 方法:
public void enroll(List<Office> offices)
{
switch (type)
{
case EnrolleeType.NEW_STUDENT:
// code goes here
// i.e. :
// lineInOfficeOne(); // after being attended to/after being serviced
// lineInOfficeTwo(); // and so on
break;
case EnrolleeType.OLD_STUDENT:
// code goes here
break;
case EnrolleeType.TRANSFEREE:
// code goes here
break;
}
}
对于每个 Enrollee 对象,我希望他们在他们需要进入的当前办公室的最短服务通道上排队。而且我认为我已经在我的 Office 类中成功地创建了一个方法 --- 它返回具有最短登记者队列的 ServiceLane 对象。
然而,问题一在于延迟所有Enrollee对象的入队方法。在现实生活中,登记者无法立即到达办公楼。登记者需要时间去那里。我打算使用计时器,但我不确定如何执行此操作。我试过了。哈哈。当我已经生成了数百个对象时,我只能将一二三Enrollee 对象排入ServiceLane 队列。我是这样做的:
public void enroll(List<Office> offices)
{
switch (walkingSpeed)
{
case EnrolleeWalkingSpeed.SLOW: divisor = 5; break;
case EnrolleeWalkingSpeed.NORMAL: divisor = 3; break;
case EnrolleeWalkingSpeed.FAST: divisor = 1; break;
}
timer.Elapsed += timer_Elapsed;
/********************************************************************/
/* REMINDER: Update currentActivity every time the enrollee gets */
/* into the next phase */
/* Make an algorithm for choosing the shortest lane */
/* (Office class's findShortestLane()) */
/********************************************************************/
switch (type)
{
case EnrolleeType.NEW_STUDENT:
performActivity(EnrolleeActivity.ACT1, offices.Find(office => office.getName().Equals("Admissions Office")));
break;
case EnrolleeType.TRANSFEREEE:
performActivity(EnrolleeActivity.ACT1, offices.Find(office => office.getName().Equals("Admissions Office")));
break;
case EnrolleeType.OLD_STUDENT:
performActivity(EnrolleeActivity.ACT9, offices.Find(office => office.getName().Equals("Finance Office")));
break;
}
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (counter % divisor == 0)
{
timer.Enabled = false;
currentOffice.findShortestLane().enqueue(this);
return;
}
counter++;
}
public void performActivity(EnrolleeActivity activity, Office office)
{
this.currentActivity = activity;
this.currentOffice = office;
timer.Enabled = true;
}
问题二是如何延迟ServiceLane对象的出列过程。当然,我们需要足够的时间来处理请求。请注意,每个 ServiceLane 一次只能将它们出列一个。
问题三是如何让 Enrollee 对象仅在其所在的当前服务通道完成与 Enrollee 对象的请求(或者更确切地说,处理时间已经已达到/已过去)。
我确实知道要搜索什么,因此这个问题的标题更有可能令人困惑。我真的不知道我是否要使用线程或计时器或其他任何东西。可能一个关键字会有所帮助。还有一段代码告诉我应该如何解决这 3 个问题。
【问题讨论】:
-
tl;博士。但看起来你混淆了实时和模拟时间。也许您应该查找“事件驱动模拟”
标签: c# multithreading timer simulation