publicobjectGetContext() { var ctx = HttpContext.Current; if (ctx == null) returnnull;
return ctx.Items[RequestContextKey]; }
publicobjectCreateContextForCurrentRequest() { var ctx = HttpContext.Current; if (ctx == null) returnnull;
object ret; ctx.Items[RequestContextKey] = ret = newobject();
return ret; } }
在 Global.ascx.cs 中调用 RedisProfiler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
protectedvoidApplication_BeginRequest() { var ctxObj = RedisProfiler.CreateContextForCurrentRequest(); if (ctxObj != null) { RedisConnection.BeginProfiling(ctxObj); } }
protectedvoidApplication_EndRequest() { var ctxObj = RedisProfiler.GetContext(); if (ctxObj != null) { var timings = RedisConnection.FinishProfiling(ctxObj); // do what you will with `timings` here } }
classAsyncLocalProfiler { privatereadonly AsyncLocal<ProfilingSession> perThreadSession = new AsyncLocal<ProfilingSession>();
public ProfilingSession GetSession() { var val = perThreadSession.Value; if (val == null) { perThreadSession.Value = val = new ProfilingSession(); } return val; } } ... var profiler = new AsyncLocalProfiler(); multiplexer.RegisterProfiler(profiler.GetSession);
以上示例会为每个异步上下文自动创建一个性能分析会话(如果上下文拥有会话,则会重用该会话)。
在某些单元测试中,可以使用以下代码来获取执行的操作和耗时:
1
var commands = profiler.GetSession().FinishProfiling();
classToyProfiler { // note this won't work over "await" boundaries; "AsyncLocal" would be necessary there privatereadonly ThreadLocal<ProfilingSession> perThreadSession = new ThreadLocal<ProfilingSession>(); public ProfilingSession PerThreadSession { get => perThreadSession.Value; set => perThreadSession.Value = value; } }
// ...
ConnectionMultiplexer conn = /* initialization */; var profiler = new ToyProfiler(); var sharedSession = new ProfilingSession();
protectedvoidApplication_EndRequest() { var session = _redisProfiler.GetSession(); if (session != null) { var timings = session.FinishProfiling(); // do what you will with `timings` here } }