停止基于布尔变量值的方法执行

时间:2017-05-04 10:30:19

标签: c# asp.net-mvc asp.net-web-api2

我正在创建用于发送电子邮件的Web Api。有两个终点

  1. / api / SendMail 这应该开始发送电子邮件,现在工作正常。
  2. / api / StopMail 这应停止发送电子邮件,此方法不会停止发送电子邮件。这是实际问题。当我达到这个终点时,我该怎么做才能阻止电子邮件。

            select_query = mysql_conn.query_db("select * from table_one where col_name like %s order by id asc limit 5", param)
    

5 个答案:

答案 0 :(得分:0)

你真的不能用ASP.NET内置的东西来做那些太多的考虑因素。控制器仅存在于一个请求的生命周期中。 ASP.NET不是为后台工作而设计的。

有一些第三方库和一个可能有帮助的内置工具。 QueueBackgroundWorkItem看起来是最有希望的。

Scott Hanselman有write up on different approaches

答案 1 :(得分:0)

您最好实现另一个类来执行包含stop标志的SendMail操作。该类可以作为单例注入控制器,并支持您所描述的启动/停止操作。

答案 2 :(得分:0)

我将使用HttpApplicationState代替stop变量: https://msdn.microsoft.com/en-us/library/system.web.httpapplicationstate.aspx

对于其他选项,请向下滚动到"服务器端状态管理选项"在本页面: https://msdn.microsoft.com/en-us/library/z1hkazw7.aspx

答案 3 :(得分:0)

您的问题有两种解决方案。我的问题是为什么你需要一个Web API来发送邮件?

  

第一解决方案

     
      
  1. 使用Windows服务。
  2.   
  3. 您可以随时停止服务。 (你甚至可以从web api停止服务)
  4.         

    第二个解决方案

         
        
    1. 使用单个API接受布尔变量
    2.   
    3. 使用计时器保持课程中的计时器变量
    4.   
    5. 需要发送电子邮件时启动计时器(当api输入时为true)//在计时器处理程序中添加此代码var emails =   db.Emails.ToList();

           

      foreach(电子邮件中的var电子邮件){//此处发送邮件的代码...     if(stop == true)break; }

    6.   
    7. 当您想要停止发送电子邮件时停止计时器(假设为api输入时)

    8.   

答案 4 :(得分:-1)

您需要拥有允许共享上下文的内容。默认情况下,控制器将拥有自己的。

您可以在共享上下文中使用类似static包装的内容来使用:

public static class EmailSenderContext {
    private static object _locker = new object();
    public static bool _canSend = true;

    public static bool CanSend() {
        var response = false;
        lock(_locker) {
            response = _canSend;
        }
        return response;
    }     

    public static void ChangeSendState(bool canSend) {
        lock(_locker) {
            _canSend = canSend;
        }
    }
}
public class MyController {
    [HttpGet]
    public void SendMail()
    {
        var emails = db.Emails.ToList();            

        foreach (var email in emails)
        {
            //code for sending mail here...

            if (!EmailSenderContext.CanSend())
                break;
        }
    }

    [HttpGet]
    public void StopMail()
    {
        EmailSenderContext.ChangeSendState(false);
    }

}

请注意,这只适用于单个服务器。您希望将其作为全局标志的那一刻,您需要引入一个数据库来存储该值,并且每次检查时都需要访问该数据库值。

这是一个 OVERLY 简化示例,对于许多系统,它将无法运行。如果这对于仅在单个服务器上运行且没有不同使用访问权限的工作项目来说是一件小事,那么它将起作用。同样,由于这是一个共享上下文,因此所有用户都可以访问该值。