如何在超过允许的时间范围内发送电子邮件的 C# 代码(或使用应用程序)?

How to C# code (or use an app) that sends emails when exceeding allowed timeframe?

我们使用自定义构建的 C# 应用程序(“通信器”)与其他几个本地安装的应用程序(Excel,...)进行交互。通信器从队列中获取输入,以定义的顺序调用应用程序(通过多个 DLL,再次自定义构建)以处理输入并将结果提交到队列。完成这些步骤所需的时间是可以预测的(第 1 步 (app1) 在 10 秒内完成,第 2 步 (app2) 在 45 秒内完成,等等)并且处理单个订单的总时间不应超过 90 秒。

大多数情况下 运行 无人值守(按设计),但有时其中一个被调用的应用程序会卡住,并且在没有人工交互的情况下无法继续。这也会停止队列处理。我们会调查原因并尝试消除它们 - 一旦检测到中断。

我们最想减少检测中断的时间 - 也许通过使用通信器或其他方法来检测是否超过了完成某个步骤的预期时间,并将这种情况通知管理员(发送电子邮件)。

你会使用通信器在每个步骤设置一个计时器,然后在超过预期完成时间时引发错误(并从其代码中发送电子邮件),或者在步骤开始时调用外部应用程序并完成并让它完成计时和通知部分以避免阻塞通信器代码?

您是否可以分享一些用于计时和发送电子邮件的代码示例? 或者可能建议一个外部应用程序接受来自通信器的启动信号并在特定时间范围内未收到完成消息时发送电子邮件?

此致

我最初是作为评论回答的,但我想我也可以做一个正确的回答。

你如何做到这一点取决于很多事情。我正在简化,因为我不知道您的代码实际是什么样子。

下面是代码的基本概要:

private async Task ExecuteStepInCommunicator(TimeSpan expectedTimeToComplete)
{
    // Maybe you want to allow for some buffer as @Oakley suggested. 
    // This will give it twice as long as the expected time to complete.
    expectedTimeToComplete = expectedTimeToComplete.Add(expectedTimeToComplete);
            
    using var alertTimer = new Timer()
    {
        Interval = expectedTimeToComplete.TotalMilliseconds,
        AutoReset = false,
    };

    alertTimer.Elapsed += this.AlertTimer_Elapsed;

    // Replace the Task.Delay with your normal 'Communicator' logic
    await Task.Delay(1000);

    // Make sure the timer is stopped once your logic has finished.
    // If it hasn't run yet, no alert will be sent. If it has run this will do nothing
    alertTimer.Stop();
}

private void AlertTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    // Send email from here. This will be called only once, when the timer elapses. 
    // https://docs.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient.send?view=net-5.0
}

System.Timer 不会阻止来自 运行ning 的正常代码。一旦计时器结束,Elapsed 回调将在线程池的线程上 运行,因此它可以 运行 即使您的通信器代码也是 运行ning。

因为这很简单,所以我建议把它放在同一个地方。您建议发送给其他应用程序来进行计时和通知,但这会增加很多复杂性(以及出错的可能性),而且收效甚微。