1

I've a requirement of creating a HttpHandler that will serve an image file (simple static file) and also it'll insert a record in the SQL Server table. (e.g http://site/some.img, where some.img being a HttpHandler) I need an in-memory object (like Generic List object) that I can add items to on each request (I also have to consider a few hundreds or thousands requests per second) and I should be able unload this in-memory object to sql table using SqlBulkCopy.

List --> DataTable --> SqlBulkCopy

I thought of using the Cache object. Create a Generic List object and save it in the HttpContext.Cache and insert every time a new Item to it. This will NOT work as the CacheItemRemovedCallback would fire right away when the HttpHandler tries to add a new item. I can't use Cache object as in-memory queue.

Anybody can suggest anything? Would I be able to scale in the future if the load is more?

4

5 回答 5

1

当您将某些内容添加到队列时,为什么 CacheItemRemovedCalledback 会触发?这对我来说没有意义......即使这确实火了,也不需要在这里任何事情。也许我误解了你的要求?

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

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

于 2008-12-29T12:44:10.100 回答
0

仅使用通用列表来存储请求并使用不同的线程来执行 SqlBulkCopy 怎么样?

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

您甚至可以通过在 CacheItemRemovedCallback 上执行工作来使后台线程基于 Cache 机制。

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

于 2008-12-29T12:43:12.740 回答
0

You can create a conditional requirement within the callback to ensure you are working on a cache entry that has been hit from an expiration instead of a remove/replace (in VB since I had it handy):

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

Edit Here it is in C# if you need it:

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;
    }
}
于 2008-12-30T15:01:37.577 回答
0

感谢 Alex 和 Bryan 的建议。

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

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

于 2008-12-29T19:56:44.127 回答
0

为了扩展我之前的评论......我得到的图片你正在错误地考虑缓存。如果您有一个对象存储在缓存中,比如一个哈希表,那么该哈希表中的任何更新/存储都将被持久化,而无需您显式修改缓存的内容。您只需将 Hashtable 添加到缓存中一次,无论是在应用程序启动时还是在第一次请求时。

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

于 2009-01-12T06:12:05.013 回答