【问题标题】:Executing function in a background process using a timer使用计时器在后台进程中执行功能
【发布时间】:2014-08-29 02:45:18
【问题描述】:

您好,我正在尝试实现此功能,其中我有一个功能可以扫描我的数据库并在一段时间(可能是 5 分钟)后返回某个值。此功能应该在后台进程中运行,并且根本不会以任何方式妨碍用户。我已经阅读了几篇关于“后台工作人员”和“线程”的文章,但我想要一些关于如何实现这一点的指导。

例如:

private void func()
{
  MessageBox.Show("Hello World!");
}

现在我希望这个函数每十五分钟执行一次,只要应用程序正在运行,一切都应该在后台进程中完成,而不会中断用户,直到最终显示消息框。

【问题讨论】:

标签: c# .net multithreading


【解决方案1】:

使用下面的示例代码:-

// Create a 1 min timer 
    timer = new System.Timers.Timer(60000);

    // Hook up the Elapsed event for the timer.
    timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

    timer.Enabled = true;


...

private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    MessageBox.Show("Hello World!");
    // Your code
}

【讨论】:

  • 很高兴它有帮助..请标记为答案,如果它有帮助@BlankEDjok
  • 快速提问,为什么我无法从这个事件中访问桌面控件?
  • 你能告诉@BlankEDjok你遇到了什么类型的错误?
  • 当我在窗体上键入控件的名称时,它只会用红色下划线。这是本次活动独有的。
  • 你能帮我看看吗?希望不会有麻烦,我真的需要能够从该事件中访问表单控件。
【解决方案2】:

有很多方法可以实现您的要求。最简单的方法是在主窗体上使用 TimerBackgroundWorker 组件。

在计时器的每个Tick 上,您调用后台工作人员的RunWorkerAsync 方法。在DoWork 事件中做你的事情,并在RunWorkerCompleted 中显示你的结果,这样你的应用程序就不会在MessageBox.Show 中运行。

【讨论】:

  • 但是如何在定时器的tick事件中执行后台worker的do_work事件呢?
【解决方案3】:
Thread t = new Thread( new ThreadStart(func));

t.start();

private void func()
{
 while(true)
 {
  MessageBox.Show("Hello World!");
  Thread.Sleep(5000);
 }
}

【讨论】:

  • 糟糕的想法。为什么要让线程长时间休眠来阻塞线程?
  • 有什么问题? @DanielKelley
  • 我认为,当您为您的意图添加一些解释时,这对 OP 和更多访问者会更有帮助。
【解决方案4】:

我不确定“完全不妨碍用户”,但是:

public static Thread Schedule(Action action, int delaysecs)
{
    return new Thread(new ThreadStart(() =>
    {
        DateTime dateTime = DateTime.Now;
        while (true) {
            if (DateTime.Now > dateTime)
            {
                action();
                dateTime.AddSeconds(delaysecs);
            }
            Thread.Sleep(1000); //Adjust for accuracy
        }
    })).Start();
}

此代码创建并返回保证每delaysecs 秒执行action 的线程。即使action 需要超过一秒,它也不会延迟下一个action,也不会影响用户体验。 (当然,如果不是很重的话。)

【讨论】:

  • 这是一个糟糕的解决方案。为什么创建一个线程只是为了让它休眠?
  • 您创建了一个线程,然后将其置于睡眠状态——这是对资源的浪费。请参阅 Neels 的回答 - 计时器更合适。
  • @DanielKelley 问题说not hinder the user at any way at all,如果是长时间操作,或者例如消息框,该计时器将中断表单或任何它正在运行的东西。
  • 如果您认为在需要定时执行操作的场景中,线程是计时器的更好选择,那么这是您的特权。我的目标是确保任何阅读此答案的人都知道 SO 上至少有 1 人不同意它。
  • 这是一个糟糕的解决方案。当一个简单的计时器可以做的时候,没有理由让一个线程有一个睡眠循环。确实,计时器可以 阻塞 UI 线程——但前提是计时器在该线程上执行。对于System.Threading.Timer,回调在池线程上执行。仅当设置了 SynchronizingObject 时,才会在 UI 线程上引发 System.Timers.Timer 事件。具有睡眠循环的线程优于计时器的情况很少见。这不是其中之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-16
相关资源
最近更新 更多