延迟方法调用和使用线程

本文关键字:线程 方法 调用 延迟 | 更新日期: 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所需的一定不同处理时间后执行取消序列。

EnrolleeServiceLanes取决于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);

在这里,您可以找到有关任务类的更多信息,这里是有关延迟方法的信息。希望这有帮助。