ASP.NET MVC与WCF,缓存通知问题

时间:2012-01-30 09:11:57

标签: asp.net wcf caching

我有一个WCF,它为我的asp.net应用程序提供数据。我想在应用程序中缓存这些数据,但我不知道是否有现成的机制来进行依赖性通知。

详细内容我需要这样的东西:

  • WCF返回数据
  • 客户端获取此数据并将其放入缓存
  • 现在客户端从其缓存中返回数据
  • 突然,WCF中的数据发生了变化
  • 客户端获取通知(?)并再次使用新数据填充缓存

如果没有现成的机制,你会如何解决?

1 个答案:

答案 0 :(得分:2)

我认为你需要的是一个自定义的CacheDependency对象,它每隔 n 秒调用一次WCF服务(其中 n 是可接受的延迟量)并与之比较以前的结果,以查看数据是否更新。然后,您的自定义依赖项可以调用其“NotifyDependencyChanged方法,该方法告诉ASP.NET底层数据已更改且缓存对象已过时。有一个关于创建自定义CacheDependency对象here的教程。

认为你的自定义CacheDependency看起来像这样(未经测试的代码):

/// <summary>
/// DTO for encapsulating stuff needed to create the dependency
/// </summary>
public class WebServiceCacheDependencySetup
{
    public object serviceClient { get; set; }
    public string clientMethod { get; set; }
    public int pollInterval { get; set; }
}

/// <summary>
/// Generic web services cache dependency
/// </summary>
public class WebServiceCacheDependency : CacheDependency
{
    private Timer timer;
    private static string previousHash;

    private object client;
    private string clientMethod;

    /// <summary>
    /// Constructor for the cache dependency
    /// </summary>
    /// <param name="setup">Object that specifies how to create dependency and call the dependent web service method</param>
    public WebServiceCacheDependency(WebServiceCacheDependencySetup setup)
    {
        // Create a timer with a specified poll interval
        timer = new Timer(CheckDependencyCallback, this, 0, setup.pollInterval);

        client = setup.serviceClient;
        clientMethod = setup.clientMethod;

        previousHash = string.Empty;
    }

    public void CheckDependencyCallback(object sender)
    {
        // Reflect on the service's proxy to find the method we want to call
        Type clientType = client.GetType();
        MethodInfo method = clientType.GetMethod(clientMethod);

        // Programmatically invoke the method and get the return value
        object returnValue = method.Invoke(client, null);

        // Cast the return to a byte array so we can hash it
        Byte[] returnBytes = (Byte[])returnValue;

        using (SHA512Managed hashAlgorithm = new SHA512Managed())
        {
            // Hash the return value into a string
            Byte[] hashedBytes = hashAlgorithm.ComputeHash(returnBytes);
            string hashedValue = Convert.ToBase64String(hashedBytes);

            // Compare the new hash to the last hash
            if (hashedValue != previousHash)
            {
                // If the hashes don't match then the web service result has changed
                // so invalidate the cached object
                NotifyDependencyChanged(this, EventArgs.Empty);

                // Tear down this instance
                timer.Dispose();
            }
        }

    }

    protected override void DependencyDispose()
    {
        if (timer != null)
        {
            timer.Dispose();
        }
    }
}