延迟方法调用和使用线程?

时间:2015-07-12 08:33:40

标签: c# multithreading timer simulation

我们说我已经得到了这段特殊代码:

/****************************************************************/
/* 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所需的一定变化处理时间后执行去队列。

ServiceLanesEnrollee的转换取决于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个问题

1 个答案:

答案 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);

Here您可以找到有关Task类的更多信息,here是有关Delay方法的信息。希望这会有所帮助。