- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为使用异步编程处理图像的 HttpModule 添加速度提升。
虽然看起来我确实获得了性能改进,但我想检查我是否正确使用了提供的工具。
我特别担心我对队列的处理不正确。
我正在采用的方法。
有很多代码所以我提前道歉但是异步编程很难:
字段
/// <summary>
/// The thread safe fifo queue.
/// </summary>
private static ConcurrentQueue<Action> imageOperations;
/// <summary>
/// A value indicating whether the application has started.
/// </summary>
private static bool hasAppStarted = false;
http模块初始化
/// <summary>
/// Initializes a module and prepares it to handle requests.
/// </summary>
/// <param name="context">
/// An <see cref="T:System.Web.HttpApplication"/> that provides
/// access to the methods, properties, and events common to all
/// application objects within an ASP.NET application
/// </param>
public void Init(HttpApplication context)
{
if (!hasAppStarted)
{
lock (SyncRoot)
{
if (!hasAppStarted)
{
imageOperations = new ConcurrentQueue<Action>();
DiskCache.CreateCacheDirectories();
hasAppStarted = true;
}
}
}
context.AddOnBeginRequestAsync(OnBeginAsync, OnEndAsync);
context.PreSendRequestHeaders += this.ContextPreSendRequestHeaders;
}
事件处理程序
/// <summary>
/// The <see cref="T:System.Web.BeginEventHandler"/> that starts
/// asynchronous processing
/// of the <see cref="T:System.Web.HttpApplication.BeginRequest"/>.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">
/// An <see cref="T:System.EventArgs">EventArgs</see> that contains
/// the event data.
/// </param>
/// <param name="cb">
/// The delegate to call when the asynchronous method call is complete.
/// If cb is null, the delegate is not called.
/// </param>
/// <param name="extraData">
/// Any additional data needed to process the request.
/// </param>
/// <returns></returns>
IAsyncResult OnBeginAsync(
object sender, EventArgs e, AsyncCallback cb, object extraData)
{
HttpContext context = ((HttpApplication)sender).Context;
EnqueueDelegate enqueueDelegate = new EnqueueDelegate(Enqueue);
return enqueueDelegate.BeginInvoke(context, cb, extraData);
}
/// <summary>
/// The method that handles asynchronous events such as application events.
/// </summary>
/// <param name="result">
/// The <see cref="T:System.IAsyncResult"/> that is the result of the
/// <see cref="T:System.Web.BeginEventHandler"/> operation.
/// </param>
public void OnEndAsync(IAsyncResult result)
{
// An action to consume the ConcurrentQueue.
Action action = () =>
{
Action op;
while (imageOperations.TryDequeue(out op))
{
op();
}
};
// Start 4 concurrent consuming actions.
Parallel.Invoke(action, action, action, action);
}
委托(delegate)和处理
/// <summary>
/// The delegate void representing the Enqueue method.
/// </summary>
/// <param name="context">
/// the <see cref="T:System.Web.HttpContext">HttpContext</see> object that
/// provides references to the intrinsic server objects
/// </param>
private delegate void EnqueueDelegate(HttpContext context);
/// <summary>
/// Adds the method to the queue.
/// </summary>
/// <param name="context">
/// the <see cref="T:System.Web.HttpContext">HttpContext</see> object that
/// provides references to the intrinsic server objects
/// </param>
private void Enqueue(HttpContext context)
{
imageOperations.Enqueue(() => ProcessImage(context));
}
最佳答案
它看起来像你的 ProcessImage
方法适用于 HttpContext
,这将是每次调用您的 HttpModule 的单个实例。 OnBeginAsync
您的 HttpModule 会根据需要在每个 Web 请求中调用,并且您的委托(delegate)已经为您提供了执行异步操作的逻辑。这意味着,您不需要 4 个并发线程,因为您只有一个 context
。无论如何,要处理的实例。而且我们不需要 ConcurrentQueue
因为所有关于 context
的工作应该在请求-响应的生命周期内完成。
总而言之,你不需要ConcurrentQueue
因为:
context
实例。ProcessImage
的工作于 context
完成从 OnEndAsync
回来之前.相反,您只想开始 ProcessImage
的后台工作在OnBeginAsync
方法,然后确保在您的 OnEndAsync
中完成工作方法。此外,由于所有更改都是直接在 context
上进行的实例(我假设,因为 ProcessImage
没有返回类型,它正在更新 context
),您不需要做任何进一步的工作来从您的处理中获取结果对象。
你可以放弃 ConcurrentQueue
并简单地使用:
IAsyncResult OnBeginAsync(object sender, EventArgs e,
AsyncCallback cb, object extraData)
{
HttpContext context = ((HttpApplication)sender).Context;
EnqueueDelegate enqueueDelegate = new EnqueueDelegate(ProcessImage);
return enqueueDelegate.BeginInvoke(context, cb, extraData);
}
public void OnEndAsync(IAsyncResult result)
{
// Ensure our ProcessImage has completed in the background.
while (!result.IsComplete)
{
System.Threading.Thread.Sleep(1);
}
}
您可以删除 ConcurrentQueue<Action> imageOperations
和 Enqueue
你也可以重命名 EnqueueDelegate
成为ProcessImageDelegate
因为它现在可以直接使用该方法。
注意:可能是您的context
尚未准备好 ProcessImage
在 OnBeginAsync
的时候.如果是这样的话,你将不得不移动ProcessImage
作为 OnEndAsync
内的简单同步调用.然而,也就是说,ProcessImage
确实有可能可以通过一些并发来改进。
我要说的另一个挑剔的观点是 hasAppStarted
可以重命名 hasModuleInitialized
减少歧义。
关于c# - 在 HttpModule 中正确使用 ConcurrentQueue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15530560/
谁能告诉我这个 HttpModule 的目的?它出现在我的 HttpModule Collection 列表中,但我不知道它的用途。 System.ServiceModel.Activation.Ht
有没有一种好方法可以排除某些页面使用 HTTP 模块? 我有一个使用自定义 HTTP 模块来验证 session 的应用程序。 HTTPModule 在 web config 中是这样设置的:
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: HTTPModule Event Execution Order? 我正在调查 Page 对象最初是在 Ht
我在服务器上安装了一个 HTTP 模块。奇怪的是它可以工作,但每隔一段时间它就不会被执行。我有日志记录,在它不起作用的时候,它没有到达记录的代码。我在 IIS 日志或事件查看器中也没有看到任何内容。
我正在尝试创建一个虚拟文件。例如,我有一个组件可以从具有给定 ID 的数据库中获取 CMS 页面。现在我有一个类似 /hello/world/ 的 url,我想将页面 /hello/world/ 解析
当调用 web 服务时,我需要在调用某些操作时更改响应文本。 因此我创建了 HttpModule 来捕获响应并更改它。 代码下方: public class BeginEnd : IHttpModul
我知道这个已经被问过了here但是答案(改为使用处理程序)并不能解决问题,因为我使用的是未实现 IHttpHandler 的第三方组件。 那么,再一次,有什么方法可以根据特定请求加载/卸载 HttpM
如何设置它们? 如果我在 HttpModule 中有以下代码。 public static event EventHandler OnPostProcessing; 并在使用 EventHandler
我已经实现了一个 HttpModule,它拦截每个请求的响应流,并在每个文本/html 类型的响应上运行六到十几个 Regex.Replace()。我担心我在这里遭受了多少性能损失。有什么好方法可以查
我有一个 HttpModule,我将几个不同的在线资源拼凑成一个(大部分)既适用于传统 ASP.NET 应用程序,也适用于 ASP.NET MVC 应用程序的东西。其中最大的一部分来自 CodePle
我试图找到一种以编程方式检查是否加载了特定 HttpModule 的方法(因为我正在编写的组件需要模块正常工作)。我正在努力: bool ismodulepresent = false; foreac
通过网络搜索,我收到很多关于 HTTPModule 路由默认是单线程还是多线程的相互冲突的帖子。 我正在尝试在本地、UAT 和部署环境中调试快速不同的性能,并且想知道 HTTPModule 是否存在我
我是否必须锁定对实例成员的访问? 示例: public class HttpModule : IHttpModule { //... Dictionary foo; void
我正在查看许多页面关于 asp.net 的性能建议。具体来说,删除未使用的 httpmodules 部分: 这里列出
从 Asp.Net 5 开始,我们现在有了“中间件”概念来更改请求和响应或与请求和响应交互。所有这些都是在使用 HttpModule 之前完成的。 这是我的问题。 到底什么是 ASP.NET 中间件?
有人知道某个站点或页面,或者知道 HTTPModule 事件执行的 HTTPApplication 类的事件的执行顺序吗? 我找到了MSDN Documentation对于所有事件,但它没有显示流程步
我正在编写一个应用程序,第三方供应商可以在其中编写插件 DLL 并将它们放入 Web 应用程序的 bin 目录中。我希望这些插件能够在必要时注册自己的 HttpModule。 无论如何,我是否可以在运
我们突然遇到 CPU 峰值。检查我们的 Sitecore 日志后,我注意到有很多日志条目带有“11:49:26 INFO HttpModule is beinginitialized”。据了解,这应该
我创建了一个简单的 HttpModule 来记录我现有网络服务的使用情况。有一个包含单个类的 dll public class TrackingModule : System.Web.IHttpMod
我正在尝试使用 HttpModule 来拦截对不包含任何代码文件(图像、音乐等)的特定目录的请求。我拥有的模块可以工作,除了它适用于所有文件夹而不仅仅是我想要它应用的文件夹。我试图在我的 web.co
我是一名优秀的程序员,十分优秀!