我有一个托管在 IIS 7 上的 WCF Web 服务。该 Web 服务提供 JSON 内容以供在移动应用程序中使用。它使用 MS SQL 2005 之上的实体框架,接口契约如下所示:
[ServiceContract]
public interface MyService
{
[WebInvoke(Method = "GET", UriTemplate = "/GetStuff?skip={skip}&take={take}&loanAmt={loanAmt}&propertyVal={propertyVal}&Term={Term}&MonthlyRent={MonthlyRent}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
ProductsDTO GetProducts(int skip, int take, decimal loanAmt, decimal propertyVal, int Term, decimal MonthlyRent);
}
实现如下所示:
public ProductsDTO GetProducts(int skip, int take, decimal loanAmt, decimal propertyVal, int Term, decimal MonthlyRent)
{
//Some set up code
using (MyEntities context = new MyEntities())
{
//Get our products
}
return ReturnedList
}
在第一次运行时,它可能需要长达 15 秒的时间(对于移动应用程序来说是不可接受的),在随后的运行中,数据会在一秒钟内返回。在 5 分钟不活动后,WCF 服务恢复为需要 15 秒才能启动。
我最初认为瓶颈在 IIS7 并且认为我的应用程序池正在关闭。在将应用程序池设置为永不回收并研究 IIS 服务器上的 w3wp.exe 进程后,我意识到情况并非如此。在这五分钟之后关闭的是数据库会话。
在这种情况下,我想保持 SQL 会话打开以立即提供来自 WCF 应用程序的请求,但是,我不想将实体上下文设置为单例或在服务中保持打开状态,因为我知道这是糟糕的做法。我可以将 SQL 连接对象传递给上下文(使用(MyEntities context = new MyEntities(MySQLConnection)))并保持打开状态?或者有人可以提出其他建议吗?
我看过很多帖子,其中的脚本会触及 Web 服务以使其保持活力,这让我感到毛骨悚然,因此我避免走这条路。
你怎么认为?
更新 1
根据 Andomars 的响应,我已将以下初始化代码添加到 WCF 服务。
public Service1()
{
// Blocking call that initializes
// the service instance
this.Initialize();
}
BackgroundWorker KeepSQLAlive = new BackgroundWorker();
private void Initialize()
{
KeepSQLAlive.DoWork += new DoWorkEventHandler(KeepSQLAlive_DoWork);
KeepSQLAlive.RunWorkerAsync();
}
void KeepSQLAlive_DoWork(object sender, DoWorkEventArgs e)
{
Timer pingback = new Timer(180000);
pingback.Elapsed += new ElapsedEventHandler(pingback_Elapsed);
pingback.Start();
}
void pingback_Elapsed(object sender, ElapsedEventArgs e)
{
using (MyEntities context = new MyEntities ())
{
context.ExecuteStoreCommand("select @@servername");
}
}
这感觉有点像捏造,我有点担心如果不将服务创建为单例,该服务将继续产生 SQL 会话而不会杀死任何会话。但是,如果它有效,这是阻力最小的路径,因为在 Windows 服务中托管此代码将花费更多时间,而且我不清楚如何将其与 IIS 安全性集成(我想使用 SSL)。我将报告上述是否有效。(感谢大家的帮助)