用于数据库循环轮询的C#计时器

时间:2010-01-06 15:44:31

标签: c# sql-server wpf database timer

到目前为止,我对C#并不是很熟悉,至少在第一次选择做某事的方式时也不够自信。

从我的WPF应用程序组织基于SQL Server数据库计时器的轮询以进行控件更新的最佳方法是什么?

您能否就这个问题分享一些想法,或者,可能代码示例如何实施?在多长时间内进行此类投票的时间有多短(或合理)?什么可能有危险?

也许有一种标准和正确的方法可以做到这一点?

3 个答案:

答案 0 :(得分:4)

您可以使用SqlDependency对象,但这会将您的实现与SQL Server 2005 +紧密联系在一起。

答案 1 :(得分:2)

如果您需要进行应用程序范围的更新,并且不会造成太多延迟来进行更新,那么最好的选择是启动可以运行的后台Thread并将事件发布给订阅者数据已刷新(可能首先通过向事件添加自定义EventArgs来检查是否已使用某些特定逻辑更改了数据。)

例如,在顶级某处创建此类的实例(可能是您的主要表单代码?):

using System;
using System.Threading;
using System.Windows.Forms;

public class PollerThread
{
    private Thread _thread;
    private SynchronizationContext _syncContext;

    public event EventHandler UpdateFinished;

    public PollerThread()
    {
        _syncContext = WindowsFormsSynchronizationContext.Current;

        ThreadStart threadStart = new ThreadStart(ThreadStartMethod);
        _thread = new Thread(threadStart);
        _thread.Name = "UpdateThread";
        _thread.IsBackground = true;
        _thread.Priority = System.Threading.ThreadPriority.Normal;
    }

    public void Start()
    {
        if ((_thread.ThreadState & ThreadState.Unstarted) == ThreadState.Unstarted)
            _thread.Start();
        else
            throw new Exception("Thread has already been started and may have completed already.");
    }

    public void ThreadStartMethod()
    {
        try
        {
            while (true)
            {
                // Go get the new data from the SQL server

                OnUpdateFinished(); // Notify all subscribers (on their own threads)
                Thread.Sleep(10000); // 10 sec wait before the next update
            }
        }
        catch (ThreadAbortException)
        {
            // The thread was aborted... ignore this exception if it's safe to do so
        }
    }

    protected virtual void OnUpdateFinished()
    {
        if (UpdateFinished != null)
        {
            SendOrPostCallback method = new SendOrPostCallback(
            delegate(object state)
            {
                UpdateFinished(this, EventArgs.Empty);
            });
            _syncContext.Send(method, null);
        }
    }
}

订阅需要响应UpdateFinished事件新更新的每个区域。这将在用于构造PollerThread类的线程上执行。

这个答案可能听起来有些松散,并且更具体地适用于Windows窗体项目,但实用性实际上取决于您当前的实现。至少你可以建立在此基础上。希望它有所帮助:)

答案 2 :(得分:1)

您的要求通常被描述,所以我只能在一般化中做出回应:

一般而言:

  1. 将同时轮询多少个应用程序?
  2. 结果集有多大?
  3. 十个客户不是很多,一万个是。十行很小,一千行变大又慢。回答这些问题将帮助您了解如何设置轮询频率。

    您需要平衡其他注意事项,例如UI响应(异步执行数据更新),对新数据的需求以及数据库更新频率的知识,以确定最有效和最有效的设计。