线程,任务,状态需要选择正确的人

时间:2019-08-07 07:00:24

标签: c# .net-core

在选择正确的工具时,我需要一些帮助。我要用树莓派替换控制某些泵的硬件控制器,并在c#.netcore中为其编写代码。泵应按特定顺序运行并持续指定时间。用所有可能的方法来实现这一目标,我正在寻找最干净有趣的方法。

泵应执行以下操作:

  • 打开泵1
  • 等待15秒
  • 打开泵2
  • 等待10分钟
  • 打开泵3
  • 让泵3运行20分钟
  • 关闭泵3
  • 等待10分钟
  • 关闭泵2
  • 等待15秒
  • 关闭泵1

我研究了计时器,线程,任务,状态机,但是我很难为这项工作选择合适的工具。在任何时候,我还需要能够立即停止所有泵。

感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

我可能会去做任务。

public async Task Execute()
{
    await TurnOnPump1();
    await Task.Delay(TimeSpan.FromSeconds(15));
    await TurnOnPump2();
    await Task.Delay(TimeSpan.FromMinutes(10));
    await TurnOnPump3();
    //And so on..
}

答案 1 :(得分:3)

要在great answer from Magnus上进行扩展,这是实现取消的方法,因此,如果您决定停止所有泵,则可以停止执行该方法(停止启动新泵)。

我发布了这个答案,因为OP明确表示他们需要能够始终停泵,因此Magnus的答案在某些情况下是行不通的。

  

在任何时候,我还需要能够立即停止所有泵。

public async Task StartAll(CancellationToken ct)
{
    await TurnOnPump1(); // no ct here because these methods should take little to no time to execute
    await Task.Delay(TimeSpan.FromSeconds(15), ct);
    await TurnOnPump2();
    await Task.Delay(TimeSpan.FromMinutes(10), ct);
    await TurnOnPump3();
    //And so on..
}

public asnyc Task StopAll()
{
    // Your_CancellationTokenSource should be defined somewhere else
    Your_CancellationTokenSource.Cancel(); // this line makes Task.Delay throw a TaskCanceledException
    await StopPump1();  
    await StopPump2();   
    await StopPump3();   
    // ..
}

public async Task HowToCallStart()
{
    try
    {
        // Your_CancellationTokenSource should be defined somewhere else
        await StartAll(Your_CancellationTokenSource.Token);
    }
    catch (TaskCanceledException)
    {
        // Starting was canceled
    }
}

这样,StopAll可以在启动过程中随时调用,而您不会遇到任何问题。

几件事要提:

  • Your_CancellationTokenSource当然应该是这些方法之外的一些变量,以便可以共享。它必须为CancellationTokenSource类型。
  • 从注释中可以看到(在代码中和下面的答案中),我认为启动泵将非常快,并且几乎不需要时间。这就是我没有通过CancellationToken的原因。 如果打开泵需要一些时间,请考虑在CancellationToken方法中使用TurnOnPumpX,如果操作被取消,则中止操作。如果这样做,您也可以简单地将ct传递给这些方法。
  • 您应在catch中添加一些有关取消操作的代码。如果最终用户不需要查看调试消息,则至少要打印出一条调试消息。