ASP.NET CacheDependency 超出线程池
在异步 http 处理程序中,我们将项目添加到 ASP.NET 缓存,并依赖于某些文件。如果异步方法在 ThreadPool 中的线程上执行,一切都很好:
AsyncResult result = new AsyncResult(context, cb, extraData);
ThreadPool.QueueUserWorkItem(new WaitCallBack(DoProcessRequest), result);
但是一旦我们尝试在 ThreadPool 之外的线程上执行:
AsyncResult result = new AsyncResult(context, cb, extraData);
Runner runner = new Runner(result);
Thread thread = new Thread(new ThreadStart(runner.Run());
...其中 Runner.Run 只是调用 DoProcessRequest,
依赖项会在线程退出。即这些项目立即从缓存中删除,原因是依赖关系。
我们想要使用池外线程,因为处理可能需要很长时间。
很明显,当我们创建线程时缺少一些东西。我们可能需要传播调用上下文、http 上下文...
有人已经遇到过这个问题吗?
注意:现成的自定义线程池可能可以解决这个问题。编写我们自己的线程池可能是一个坏主意(想想 NIH 综合症)。但我想详细了解这一点。
In an async http handler, we add items to the ASP.NET cache, with dependencies on some files. If the async method executes on a thread from the ThreadPool, all is fine:
AsyncResult result = new AsyncResult(context, cb, extraData);
ThreadPool.QueueUserWorkItem(new WaitCallBack(DoProcessRequest), result);
But as soon as we try to execute on a thread out of the ThreadPool:
AsyncResult result = new AsyncResult(context, cb, extraData);
Runner runner = new Runner(result);
Thread thread = new Thread(new ThreadStart(runner.Run());
... where Runner.Run just invokes DoProcessRequest,
The dependencies do trigger right after the thread exits. I.e. the items are immediately removed from the cache, the reason being the dependencies.
We want to use an out-of-pool thread because the processing might take a long time.
So obviously something's missing when we create the thread. We might need to propagate the call context, the http context...
Has anybody already encountered that issue?
Note: off-the-shelf custom threadpools probably solve this. Writing our own threadpool is probably a bad idea (think NIH syndrom). Yet I'd like to understand this in details, though.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
无法弄清楚详细信息...
不过,找到了一种解决方法:在大多数 IAsyncResult 实现中,一旦操作完成,就会直接调用回调。我们替换了它,现在将回调排队到线程池中。因此,回调在 ThreadPool 中执行,并且可以注册最后的依赖项。
Could not figure out the details...
Found a workaround, though: in most IAsyncResult implementation, once the operation is completed there is a direct call to the callback. We replaced this, and now queue the callback into the ThreadPool. Hence, the callback executes within the ThreadPool and can register dependencies that last.