Rob*_*ool 6 asp.net iis-7 caching iis-6
这只清除用户缓存中的项目:
public static void ClearCache()
{
foreach (DictionaryEntry entry in HttpRuntime.Cache)
{
HttpRuntime.Cache.Remove(entry.Key.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法访问内核缓存?
澄清:我想打印内核缓存中所有项的键,作为奖励,我希望能够从C#方法中清除内核缓存.
Jus*_*ant 11
是的,可以通过编程方式枚举和删除IIS内核缓存中的项目.
注意事项:
列举:
我知道枚举IIS内核缓存的唯一记录方式是IIS7及更高版本中可用的命令行应用程序(尽管您可以将NETSH帮助程序DLL从V7复制到V6系统 - 尚未尝试过).
netsh http show cachestate
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,请参阅show cachestate命令的MSDN文档.您可以通过执行该过程并解析文本结果将其转换为"API".
Big Caveat:我从未见过这个命令行应用实际上在我的服务器上返回任何内容,即使是在经典模式下运行的应用程序.不知道为什么 - 但应用程序确实有效,因为我可以在网上看到其他帖子.(例如http://chrison.net/ViewingTheKernelCache.aspx)
如果你对进程创建非常过敏并且有野心勃勃,那么NETSH命令是由带有文档化的Win32接口的DLL实现的,因此你可以编写假装它的NETSH.exe并直接调用IIS的NETSH助手DLL的代码.您可以使用MSDN上的文档作为此方法的起点.警告:模拟NETSH是非常困难的,因为接口是双向的:NETSH调用DLL并且DLL调用回NETSH.而且你仍然需要解析文本输出,因为NETSH接口是基于文本的,而不是基于对象的,如PowerShell或WMI.如果是我,我只会产生一个NETSH流程.;-)
这有可能是在IIS7的PowerShell管理单元可以支持未来(指除上述黑客更容易的编程访问)此功能,但据我所知只有NETSH今天支持此功能.
无效:
我有好消息和坏消息.
好消息:一旦你知道要从IIS的内核缓存中提取的项目的URL,就可以在IIS6及更高版本上使用Win32 API将其删除.这可以通过P/Invoke(更难)从C#调用,也可以通过将调用放入托管C++包装器DLL中调用.有关详细信息,请参阅MSDN上的HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK.
我接受了所需的代码(附在下面).警告:它是丑陋且未经测试的 - 它不会使我的IIS崩溃但是(见上文)我无法弄清楚如何使缓存枚举工作,所以我实际上无法使用有效的URL来调用它来从缓存中提取.如果您可以使枚举工作,那么插入有效的URL(并因此测试此代码)应该很容易.
坏消息:
这是一些代码:
using System;
using System.Web;
using System.Reflection;
using System.Runtime.InteropServices;
public partial class Test : System.Web.UI.Page
{
/// Return Type: BOOL->int
public delegate int GetServerVariable();
/// Return Type: BOOL->int
public delegate int WriteClient();
/// Return Type: BOOL->int
public delegate int ReadClient();
/// Return Type: BOOL->int
public delegate int ServerSupportFunction();
/// Return Type: BOOL->int
public delegate int EXTENSION_CONTROL_BLOCK_GetServerVariable();
/// Return Type: BOOL->int
public delegate int EXTENSION_CONTROL_BLOCK_WriteClient();
/// Return Type: BOOL->int
public delegate int EXTENSION_CONTROL_BLOCK_ReadClient();
/// Return Type: BOOL->int
public delegate int EXTENSION_CONTROL_BLOCK_ServerSupportFunction();
public static readonly int HSE_LOG_BUFFER_LEN = 80;
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
public struct EXTENSION_CONTROL_BLOCK
{
/// DWORD->unsigned int
public uint cbSize;
/// DWORD->unsigned int
public uint dwVersion;
/// DWORD->unsigned int
public uint connID;
/// DWORD->unsigned int
public uint dwHttpStatusCode;
/// CHAR[HSE_LOG_BUFFER_LEN]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 80 /*HSE_LOG_BUFFER_LEN*/)]
public string lpszLogData;
/// LPSTR->CHAR*
public System.IntPtr lpszMethod;
/// LPSTR->CHAR*
public System.IntPtr lpszQueryString;
/// LPSTR->CHAR*
public System.IntPtr lpszPathInfo;
/// LPSTR->CHAR*
public System.IntPtr lpszPathTranslated;
/// DWORD->unsigned int
public uint cbTotalBytes;
/// DWORD->unsigned int
public uint cbAvailable;
/// LPBYTE->BYTE*
public System.IntPtr lpbData;
/// LPSTR->CHAR*
public System.IntPtr lpszContentType;
/// EXTENSION_CONTROL_BLOCK_GetServerVariable
public EXTENSION_CONTROL_BLOCK_GetServerVariable GetServerVariable;
/// EXTENSION_CONTROL_BLOCK_WriteClient
public EXTENSION_CONTROL_BLOCK_WriteClient WriteClient;
/// EXTENSION_CONTROL_BLOCK_ReadClient
public EXTENSION_CONTROL_BLOCK_ReadClient ReadClient;
/// EXTENSION_CONTROL_BLOCK_ServerSupportFunction
// changed to specific signiature for invalidation callback
public ServerSupportFunction_HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK ServerSupportFunction;
}
/// Return Type: BOOL->int
///ConnID: DWORD->unsigned int
///dwServerSupportFunction: DWORD->unsigned int
///lpvBuffer: LPVOID->void*
///lpdwSize: LPDWORD->DWORD*
///lpdwDataType: LPDWORD->DWORD*
[return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
public delegate bool ServerSupportFunction_HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK(
uint ConnID,
uint dwServerSupportFunction, // must be HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK
out Callback_HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK lpvBuffer,
out uint lpdwSize,
out uint lpdwDataType);
public readonly uint HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK = 1040;
// typedef HRESULT (WINAPI * PFN_HSE_CACHE_INVALIDATION_CALLBACK)(WCHAR *pszUrl);
[return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
public delegate bool Callback_HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK(
[MarshalAs(UnmanagedType.LPWStr)]string url);
object GetField (Type t, object o, string fieldName)
{
FieldInfo fld = t.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
return fld == null ? null : fld.GetValue(o);
}
protected void Page_Load(object sender, EventArgs e)
{
// first, get the ECB from the ISAPIWorkerRequest
var ctx = HttpContext.Current;
HttpWorkerRequest wr = (HttpWorkerRequest) GetField(typeof(HttpContext), ctx, "_wr");
IntPtr ecbPtr = IntPtr.Zero;
for (var t = wr.GetType(); t != null && t != typeof(object); t = t.BaseType)
{
object o = GetField(t, wr, "_ecb");
if (o != null)
{
ecbPtr = (IntPtr)o;
break;
}
}
// now call the ECB callback function to remove the item from cache
if (ecbPtr != IntPtr.Zero)
{
EXTENSION_CONTROL_BLOCK ecb = (EXTENSION_CONTROL_BLOCK)Marshal.PtrToStructure(
ecbPtr, typeof(EXTENSION_CONTROL_BLOCK));
uint dummy1, dummy2;
Callback_HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK invalidationCallback;
ecb.ServerSupportFunction(ecb.connID,
HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK,
out invalidationCallback,
out dummy1,
out dummy2);
bool success = invalidationCallback("/this/is/a/test");
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2926 次 |
| 最近记录: |