我们说我已经得到了这段特殊代码:
/****************************************************************/
/* 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()
的函数,它接受一个参数,该参数是Office
可能去的所有Enrollee
个对象的列表。
每个Office
对象都有一个ServiceLane
个对象列表。这些ServiceLane
个对象的队列为Enrollees
;以及称为enqueue()
和dequeue()
的方法。 enqueue()
只接受Enrollee
类型的参数,并将其添加到enrolleesInLine
列表中,该列表说明Enrollee
对象上排队的ServiceLane
个对象。当然,dequeue()
方法会执行出列,但我需要它在ServiceLane
所需的一定变化处理时间后执行去队列。
ServiceLanes
和Enrollee
的转换取决于Enrollee
的类型和他们需要进入的当前Office
,因此,我构建了{enroll()
1}}这样的方法:
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的最短Service Lane上排队。我认为我已经在我的Office类中成功创建了一个方法 - 它返回具有最短登记队列的ServiceLane对象。
然而,问题一在于延迟所有Enrollee对象的enqueue方法。在现实生活中,参与者不能立即到达办公楼。登记者需要时间去那里。我打算使用计时器,但我不确定如何做到这一点。我试过了。大声笑。我只能在Enrollee
上排队一两三个ServiceLane
个对象,而我已经生成了数百个。{1}}。以下是我的表现方式:
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个问题。
答案 0 :(得分:0)
我认为你可以使用Task类来实现你的目标。 它有Delay方法,接受延迟时间(以毫秒为单位),你可以在延迟时间之后设置ContinuationTask,这里是例子:
Stopwatch sw = Stopwatch.StartNew();
var delay = Task.Delay(1000).ContinueWith(_ =>
{ sw.Stop();
return sw.ElapsedMilliseconds; } );
Console.WriteLine("Elapsed milliseconds: {0}", delay.Result);