【发布时间】:2011-06-06 14:51:20
【问题描述】:
我正在开发一个我希望有两个线程的 Windows 服务。一个线程应查找更新(在 RSS 提要中)并在找到更新时将行插入数据库。
当发现更新时,我想通过另一个线程发送通知,该线程访问数据库,获取消息和收件人,然后发送通知。
也许最好的做法是不要使用两个线程。我应该在两个线程中都有 db-connections 吗?
谁能告诉我如何解决这个问题?
【问题讨论】:
我正在开发一个我希望有两个线程的 Windows 服务。一个线程应查找更新(在 RSS 提要中)并在找到更新时将行插入数据库。
当发现更新时,我想通过另一个线程发送通知,该线程访问数据库,获取消息和收件人,然后发送通知。
也许最好的做法是不要使用两个线程。我应该在两个线程中都有 db-connections 吗?
谁能告诉我如何解决这个问题?
【问题讨论】:
使应用程序或服务成为多线程的主要原因是执行数据库或其他后台操作,而不会阻塞(即挂起)像 Windows 窗体这样的表示元素。如果您的服务依赖于非常快速的轮询或期望数据库插入需要很长时间,那么使用两个线程可能是有意义的。但我无法想象在你的场景中会出现这种情况。
如果您决定让您的服务成为多线程的,那么您要研究的 C# 中的两个主要类是 BackgroundWorker 和 ThreadPool。如果您想执行多个并发数据库插入(例如,如果您想为同时轮询的多个 RSS 提要中的每一个执行插入),您应该使用 ThreadPool。否则,请使用 BackgroundWorker。
通常,您会有一个数据库访问类,它有一个插入行的方法。该方法将创建一个后台工作程序,将 DoWork 处理程序添加到该数据库访问类中的某个静态方法到后台工作程序,然后调用 DoWorkAsync。您应该只在该类中具有数据库连接设置,以便更轻松地维护代码。例如:
public static class DbAccess
{
public void InsertRow(SomeObject entity)
{
BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += InsertRow_DoWork;
bg.RunWorkerCompleted += InsertRow_RunWorkerCompleted;
bg.RunWorkerAsync(entity);
}
private void InsertRow_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bg = sender as BackgroundWorker;
SomeObject entity = e.Argument as SomeObject;
// insert db access here
}
private void InsertRow_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// send notifications
// alternatively, pass the InsertRow method a
// delegate to a method in the calling class that will notify
}
}
【讨论】: