需要建议ASP.Net内存中的队列

时间:2008-12-29 03:19:16

标签: asp.net httphandler

我需要创建一个HttpHandler来提供图像文件(简单的静态文件),并且它还会在SQL Server表中插入一条记录。 (例如http://site/some.img,其中some.img是一个HttpHandler)我需要一个内存中的对象(比如Generic List对象),我可以在每个请求上添加项目(我还需要考虑几百或几千个请求)每秒)我应该能够使用SqlBulkCopy将此内存中对象卸载到sql表。

列表 - > DataTable - > SqlBulkCopy的

我想过使用Cache对象。创建一个通用列表对象并将其保存在HttpContext.Cache中,并在每次向其添加新项时插入。这将不起作用,因为当HttpHandler尝试添加新项时,CacheItemRemovedCallback会立即触发。我不能将Cache对象用作内存中队列。

任何人都可以提出任何建议吗?如果负载更大,我将来能够扩展吗?

5 个答案:

答案 0 :(得分:1)

为什么在向队列添加内容时会激活CacheItemRemovedCalledback?这对我来说没有意义......即使确实如此,也没有要求这里的任何事情。也许我误解了你的要求?

我已经非常成功地以这种方式使用了Cache对象。这就是它的设计目标,并且可以很好地扩展。我存储了一个Hashtable,它可以在每个应用页面请求中访问,并根据需要进行更新/清除。

选项二......你真的需要队列吗?如果您只想直接写入数据库,SQL Server也可以很好地扩展。使用共享连接对象和/或连接池。

答案 1 :(得分:0)

如何使用通用列表存储请求并使用不同的线程来执行SqlBulkCopy?

这样在列表中存储请求不会阻止响应太长时间,后台线程将能够自己更新Sql,每5分钟一次。

您甚至可以通过执行CacheItemRemovedCallback上的工作将后台线程建立在Cache机制上。

只需插入一些物体,移除时间为5分钟,然后在处理工作结束时重新插入。

答案 2 :(得分:0)

感谢Alex&布莱恩为你的建议。

Bryan:当我尝试在第二个请求中替换Cache中的List对象时(现在,count应为2),当我用新的Cache对象替换当前的Cache对象时,CacheItemRemovedCalledback会触发。最初,我也认为这是奇怪的行为所以我要深入研究它。 另外,对于第二个建议,我将尝试插入记录(使用Cached SqlConnection对象)并查看我在进行压力测试时获得的性能。我怀疑我会得到很棒的数字,因为它是I / O操作。

我会继续挖掘我的最佳解决方案,同时提出你的建议。

答案 3 :(得分:0)

你可以在回调中创建一个条件要求,以确保你正在处理一个已经过期而不是删除/替换的缓存条目(在VB中,因为我把它用得很方便):

Private Shared Sub CacheRemovalCallbackFunction(ByVal cacheKey As String, ByVal cacheObject As Object, ByVal removalReason As Web.Caching.CacheItemRemovedReason)
    Select Case removalReason
        Case Web.Caching.CacheItemRemovedReason.Expired, Web.Caching.CacheItemRemovedReason.DependencyChanged, Web.Caching.CacheItemRemovedReason.Underused
        ' By leaving off Web.Caching.CacheItemRemovedReason.Removed, this will exclude items that are replaced or removed explicitly (Cache.Remove) '
    End Select
End Sub

编辑如果您需要,请使用C#:

private static void CacheRemovalCallbackFunction(string cacheKey, object cacheObject, System.Web.Caching.CacheItemRemovedReason removalReason)
{
    switch(removalReason)
    {
        case System.Web.Caching.CacheItemRemovedReason.DependencyChanged:
        case System.Web.Caching.CacheItemRemovedReason.Expired:
        case System.Web.Caching.CacheItemRemovedReason.Underused:
            // This excludes the option System.Web.Caching.CacheItemRemovedReason.Removed, which is triggered when you overwrite a cache item or remove it explicitly (e.g., HttpRuntime.Cache.Remove(key))
            break;
    }
}

答案 4 :(得分:0)

要扩展我以前的评论...我得到的图片你正在考虑缓存不正确。如果你有一个存储在Cache中的对象,比如一个Hashtable,那么Hashtable中的任何更新/存储都将被保留,而不会显式修改Cache的内容。您只需要在应用程序启动时或第一次请求时将Hashtable添加到缓存一次。

如果您担心同时发生批量复制和页面请求更新,那么我建议您简单地使用两个缓存列表。有一个是在页面请求进入时更新的列表,以及一个用于批量复制操作的列表。完成一个批量复制后,交换列表并重复。这类似于视频游戏或视频应用的双缓冲视频RAM。