I want to start a new thread to query a database while my web application continues running. I was under the impression that by using threads I can run the querying process independently while the normal web application page cycle carries on, but I could be wrong.
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);
}
}
}
It seems to basically stall and wait to finish the query before loading the page (which can be thousands of rows, so it takes awhile). I put this in the following section of Global.asax
:
protected void Application_Start(object sender, EventArgs e)
{
DbAsyncQuery query = new DbAsyncQuery();
query.UpdateBillingDB();
}
This is one of my first web pages, and I'm new to threading. I understand there is a difference between creating your own thread and using the ThreadPool. In this method, I am using my own thread, I think. Not sure if that's the best way.
Any ideas? The querying process can be completely independent, and its o开发者_Python百科nly going to occur on scheduled intervals (every 8 hours or so). The user doesn't need to have up to the minute data, so it can take awhile. I just don't want the site to wait for it to finish, if that's possible.
Since your database process runs on a schedule, then keep it out of the web application. Create a console application that does this process and use Windows's Scheduled Tasks to schedule it to run every 8 hours.
Put code that is common to the database procedure and web site in a shared dll.
The reason you want to separate this is:
Web app won't run if there are no clients. If you want this to run on a schedule, take control of the schedule, don't leave it up to clients hitting the website to trigger.
Separate resources. Since this routine is long running keep the resources it uses separate from the web site. Using a console app also 100% cleans up any resources it uses automatically when it closes.
Simpler to program. While it may sound more complicated at first to manage separate products, separating them and concentrating on things one at a time will actually simplify development.
Run to completion. The ASP.NET worker process recycles based on many conditions, including a set schedule, and a long-running process won't keep it from recycling. If it recycles while your process is running, your process won't complete. Separating it to a scheduled task will ensure it's allowed to run to completion regardless of ASP.NET worker process state or recycles.
精彩评论