在Web应用程序继续运行时,如何在第二个线程上查询数据库?

时间:2011-02-11 04:08:18

标签: c# asp.net multithreading web-services

我想在我的Web应用程序继续运行时启动一个新线程来查询数据库。我的印象是,通过使用线程,我可以独立运行查询过程,而正常的Web应用程序页面循环继续,但我可能是错的。

public class DbAsyncQuery
{
    Dictionary<string, object> serviceResults = new Dictionary<string, object>();

    public void UpdateBillingDB()
    {
        QueryAllServices();

        foreach (KeyValuePair<string, object> p in serviceResults)
        {
            IEnumerable results = (IEnumerable)p.Value;
            IEnumerable<object> sessions = results.Cast<object>();

            DbUtil.MakeBillingDBEntry(sessions, p.Key);
        }
    }

    public static string[] servicesToQuery = new string[]    // Must go in config file ultimately 
    {
        "xxx.x.xxx.xx"

    };

    public delegate void Worker(); 

    private Thread worker;

    public void InitializeThread(Worker wrk)
    {
        worker = new Thread(new ThreadStart(wrk));
        worker.Start();
    }

    public void InitializeQuery()
    {
        Worker worker = QueryAllServices;
        InitializeThread(worker);
    }

    private void QueryAllServices()
    {
        Dictionary<string, DateTime> lastEntries = DbUtil.GetLastEntries();

        foreach (string ip in servicesToQuery)
        {
            string fullServicePath =
                "http://" + ip + ":800/MyWebService.asmx";

            //object[] lastEntry = new object[] { lastEntries[ip] };
            object[] lastEntry = new object[] { new DateTime(2011, 1, 1, 0, 0, 0) }; 

            object obj = WebServiceHandler.CallWebService
                (fullServicePath, "MyWebService", "GetBillingDBEntries", lastEntry);

            serviceResults.Add(ip, obj);
        }
    }
}

它似乎基本上停止并等待在加载页面之前完成查询(可能是数千行,因此需要一段时间)。我把它放在Global.asax的以下部分中:

protected void Application_Start(object sender, EventArgs e)
{
    DbAsyncQuery query = new DbAsyncQuery();
    query.UpdateBillingDB(); 
}

这是我的第一个网页之一,我是线程新手。我知道创建自己的线程和使用ThreadPool之间存在差异。在这种方法中,我认为我正在使用自己的线程。不确定这是不是最好的方法。

有什么想法吗?查询过程可以完全独立,并且只能按计划的时间间隔(每8小时左右)进行一次。用户不需要具有最新的数据,因此可能需要一段时间。我只是不希望网站等待它完成,如果可能的话。

1 个答案:

答案 0 :(得分:1)

由于您的数据库进程按计划运行,因此请将其保留在Web应用程序之外。创建一个执行此过程的控制台应用程序,并使用Windows的计划任务将其安排为每8小时运行一次。

将数据库过程和网站常用的代码放在共享的dll中。

您要将其分开的原因是:

  1. 如果没有客户端,Web应用程序将无法运行。如果您希望按计划运行,请控制时间表,不要让客户点击网站触发。

  2. 分开资源。由于此例程长时间运行,因此请将其使用的资源与Web站点分开。使用控制台应用程序时,100%会清除它关闭时自动使用的所有资源。

  3. 编程更简单。虽然一开始管理单独的产品听起来可能更复杂,但将它们分开并一次只关注一件事实际上会简化开发。

  4. 运行至完成。 ASP.NET工作进程基于许多条件(包括设置的计划)进行回收,并且长时间运行的进程不会使其无法回收。如果它在您的流程运行时进行回收,则您的流程将无法完成。将其分离到计划任务将确保无论ASP.NET工作进程状态还是回收,都允许它运行完成。