Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何安全有效地缓存ADO.NET命令?_C#_.net_Asp.net_Vb.net_Ado.net - Fatal编程技术网

C# 如何安全有效地缓存ADO.NET命令?

C# 如何安全有效地缓存ADO.NET命令?,c#,.net,asp.net,vb.net,ado.net,C#,.net,Asp.net,Vb.net,Ado.net,我想使用这种模式: SqlCommand com = new SqlCommand(sql, con); com.CommandType = CommandType.StoredProcedure;//um com.CommandTimeout = 120; //com.Connection = con; //EDIT: per suggestions below SqlParameter par; par = new SqlParameter("@id", SqlDbType.Int);

我想使用这种模式:

SqlCommand com = new SqlCommand(sql, con);
com.CommandType = CommandType.StoredProcedure;//um
com.CommandTimeout = 120;
//com.Connection = con;  //EDIT: per suggestions below

SqlParameter par;
par = new SqlParameter("@id", SqlDbType.Int);
par.Direction = ParameterDirection.Input;

com.Parameters.Add(par);

HttpContext.Current.Cache["mycommand"] = com;
很明显,我不想遇到一些奇怪的问题,比如A个人从缓存中检索这个,更新param1,2个人从缓存中获取它,更新param2,以及每个运行命令的用户混合使用这两者

克隆从缓存中取出的命令可能比从头创建一个新命令更昂贵

ASP.NET缓存的线程安全性如何?我是否遗漏了其他潜在的陷阱?尽管存在线程问题,这种技术是否适用于无参数命令


克莱尔化:如果我想打自己的脚,我该如何瞄准?有没有一种方法可以锁定对缓存中对象的访问,以便对其进行序列化?

缓存本身是线程安全的,但不会对放置在其中的对象赋予线程安全性。SqlCommand对象不是线程安全的,因此不是您希望缓存的类型

在这个场景中,最重要的事情是缓存为您处理的连接,您不应该试图自己处理这个问题

创建命令对象(即使是一个有许多参数的对象)与其执行相比仍然是微不足道的。除非你有相反的证据,否则不要试图缓存它们


项目面临的最大风险是过早优化。

很简单:不要。如果您看不出这是错误的,您需要在ADO.NET上阅读更多内容。有很多文献解释了正确的方法:只需在需要时创建连接和命令,并确保正确处理它们。

正如其他人所说,这是一个全面的坏主意。这是个坏主意的原因有很多

最重要的是,如果您处于高负载情况下,为每个用户存储命令将非常快地填满缓存,并且根据优先级等,将开始导致其他项从缓存中掉出,这应该仍然存在

使用ADO.NET,您确实应该在使用命令和连接时创建、使用并处理它们。就性能而言,我从来没有改变过这个系统……我也没有听说过很多其他人也这样做过


另外,正如其他人在代码示例中提到的,实际执行所需的连接无论如何都会丢失。

为什么要缓存该命令?创建命令的开销很小,您只需新建几个对象并设置一些属性。我不认为这是个瓶颈


您希望缓存命令的结果,因为实际执行命令的成本(相对)较高。通常,您希望将共享缓存视为只读,这样就不必担心锁定和同步访问。缓存结果可以实现这一点。

缓存结果,并且仅在resultcache为空时创建连接(和命令):

伪代码:

result = getResultFromCache(CacheKey)
if (result == null)
{
     result = getResultFromDB();
     InsertIntoCache(result,cacheKey);
}

return result;

我应该询问如何在ASP.NET缓存中锁定项目,而不是说我打算在缓存中放置什么

lock(Cache)
  {
    // do something with cache that otherwise wouldn't be threadsafe
  }

参考资料:

IMHO比链接文章中的更好的解决方案是在缓存中放置线程安全对象:这可以是非线程安全对象的线程安全包装。