延迟方法调用和使用线程
本文关键字:线程 方法 调用 延迟 | 更新日期: 2023-09-27 18:02:13
假设我有这段特定的代码:
/****************************************************************/
/* 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
列表中,该列表表示在ServiceLane
对象上排队的Enrollee
对象。当然,dequeue()
方法执行取消排队,但我需要它在ServiceLane
所需的一定不同处理时间后执行取消序列。
Enrollee
去ServiceLanes
取决于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;
}
}
对于每个登记者对象,我希望他们在当前办公室上需要进入的最短服务通道上排队。我想我已经在我的 Office 类中成功创建了一个方法,---它返回具有最短注册者队列的 ServiceLane 对象。
但是,问题一在于延迟所有登记者对象的排队方法。在现实生活中,登记者无法立即到达办公楼。登记者需要时间去那里。我打算使用计时器,但我不确定如何做到这一点。我试过了。哈哈。而且我只能得到一个一二三个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 个问题。
我认为您可以使用任务类来实现您的目标。它具有延迟方法,该方法接受以毫秒为单位的延迟时间,您可以在该延迟时间之后设置ContinuationTask,这是示例:
Stopwatch sw = Stopwatch.StartNew();
var delay = Task.Delay(1000).ContinueWith(_ =>
{ sw.Stop();
return sw.ElapsedMilliseconds; } );
Console.WriteLine("Elapsed milliseconds: {0}", delay.Result);
在这里,您可以找到有关任务类的更多信息,这里是有关延迟方法的信息。希望这有帮助。