【问题标题】:Better way to constantly run function periodically in C#在 C# 中定期运行函数的更好方法
【发布时间】:2013-05-02 22:40:27
【问题描述】:

我有一个 C# 程序,它不断检查在线数据库的新增内容。我有这段代码让它每 10 秒检查一次

    static void Main(string[] args)
    {
        boolean run = true;
        while (run)
        {
            DBConnect Db = new DBConnect();

            // do amazing awesome mind blowing cool stuff

            Db.closeConnection();

            // wait for 10 seconds
            int wait = 10 * 1000;
            System.Threading.Thread.Sleep(wait);
        }
    }

我有发布到数据库的错误报告,如果发生重大错误,程序将关闭。除了我的函数中的特定错误之外,这种方法是否安全有效?

【问题讨论】:

  • 您对“安全”和“高效”的定义是什么?
  • 是什么让你觉得与众不同?
  • 高效 = 不使用不必要的资源,安全 = 稳定运行的稳定程序@PeteBaughman
  • 这听起来像是一个使用 Sql Dependency msdn.microsoft.com/en-CA/library/a52dhwx7(v=vs.80).aspx 的好案例
  • 你也可以运行计时器而不是线程睡眠,不过这是一件小事。

标签: c# wait


【解决方案1】:

您应该将您的程序重写为 Windows 服务,这样您就无需依赖用户登录来运行您的程序。

如果您确实使用服务路线,我会将无限循环换成计时器。

public partial class Service1 : ServiceBase
{
    public Service1()
    {
        InitializeComponent();
        int wait = 10 * 1000;
        timer = new Timer(wait);
        timer.Elapsed += timer_Elapsed;

        // We don't want the timer to start ticking again till we tell it to.
        timer.AutoReset = false;
    }

    private System.Timers.Timer timer;

    protected override void OnStart(string[] args)
    {
        timer.Start();
    }

    void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        try
        {
            DBConnect Db = new DBConnect())
            try
            {
                // do amazing awesome mind blowing cool stuff
            }
            finally
            {
                Db.closeConnection(); //We put this in a finally block so it will still happen, even if an exception is thrown.
            }
            timer.Start();
         }
         catch(SomeNonCriticalException ex)
         {
             MyExecptionLogger.Log(ex, Level.Waring); //Log the exception so you know what went wrong
             timer.Start(); //Start the timer for the next loop
         }
         catch(Exception ex)
         {
             MyExecptionLogger.Log(ex, Level.Critical); //Log the exception so you know what went wrong
             this.Stop(); //Stop the service
         }
    }

    protected override void OnStop()
    {
        timer.Stop();
    }
}

【讨论】:

  • 非常酷,所以无论登录哪个用户,Windows 服务基本上都在后台运行?喜欢 svchost?
  • 对,就是服务的定义
  • 非常简单有效,感谢您花时间赐教!
  • @Dan 您想处理程序在出现问题的情况下执行的操作。我更新了我的代码以记录到一个虚构的函数,然后在抛出异常时停止服务。
【解决方案2】:

将其编写为控制台程序,无需等待,并设置计划任务以定期运行它。您想每 10 秒运行一次吗?每一分钟?只需更改计划任务即可。

您可以使用任务计划程序 GUI,或 schtasks 命令行工具。

Programs are not cats

【讨论】:

  • 天哪,这也是一个不错的选择——我不知道该选择哪个答案!
  • 猫是怎么回事? :) 也是一个不错的选择,请投票
【解决方案3】:

我会设置一个 Windows 服务并使用SqlDependencyhttp://msdn.microsoft.com/en-CA/library/a52dhwx7(v=vs.80).aspx。这样,当数据库中发生更改(您指定)时,它将触发您指定的 OnChange 事件以执行您需要执行的任何操作。实现细节见链接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 2019-10-21
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多