Caching member return value fails when using a params collection

Topics: Caching Application Block
Sep 22, 2009 at 1:13 PM
Edited Sep 22, 2009 at 1:17 PM

Hi!

I have the following problem: I am using the Caching Application Block to cache member return values. This works well until i am using params collections in my method signature.

Is there anybody who experienced the same problem?

Expressed in code this means:

// result (DataSet) is cached

DataSet pW_Test(Int32 intValue)

 

// result (DataSet) is NOT cached

DataSet pW_TestParams(Int32 intValue, params int[] intParams)

 

pW_TestParams' result isn't cached even if i call it without the params collection (e.g. pW_TestParams(1);)

Sep 22, 2009 at 2:20 PM
Edited Sep 22, 2009 at 2:21 PM

Hi,

Can you post your implementation of both methods? I've tried doing the same and the return values are successfully cached.

Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Sep 22, 2009 at 2:35 PM
public interface IDataAccess_C
{
     [Tag("Caching")]
     DataSet pW_TestParams(Int32 intValue, params int[] returnValue);
     [Tag("Caching")]
     DataSet pW_Test(Int32 intValue);
}
public class DataAccess_C : DataAccess, IDataAccess_C
{
    public DataSet pW_TestParams(Int32 intValue, params int[] returnValue)
    {
        if(returnValue != null && returnValue.Length > 0) returnValue[0] = 1;
        return new DataSet();
    }

    public DataSet pW_Test(Int32 intValue)
    {
        return new DataSet();
    }
}

I have configured a Caching Handler via a Tag Attribute Matching Rule ("Caching").

Thx for looking into this!

Markus

Sep 23, 2009 at 4:05 AM

Hi,

I've repro your problem. It seems that you are calling the same method consecutively with the same input parameter? Is that correct? According to the documentation (http://msdn.microsoft.com/en-us/library/dd140022.aspx), it is a expected behavior. That when a method is invoked, the CachingCallHandler creates a key based on the method signature and input parameter. So, the second time you call the same method with the same parameter, it will just return the cached value. For more of the CachingCallHandler behavior please see the link above.

Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Sep 23, 2009 at 5:52 AM
Edited Sep 23, 2009 at 5:54 AM

Hi,

You are right, I am calling "pW_TestParams(1);" (leaving out the params). And if you're telling me that I should get a cached value if i call the method twice this is exactly what I would expect. But in my case, if i call the method again with the same parameter, it does not return the cached value it just steps into the method again. It's working with "pW_test(1);" but not with "pW_TestParams(1);" ...

So I am not wondering why a value gets cached i am wondering why it doesn't.

Markus

Sep 23, 2009 at 5:59 AM

I haven't tested this, but I have a theory. Under the hood, a varargs (params) method actually receives an array of whatever type the argument is. When you call pW_TestParams(1), the call actually looks like:

pW_TestParams(1, new int[0]);

The problem is that the new int[0] part returns a new empty array every time. They don't compare equal, so the handler considers them separate values and the cache doesn't hit.

-Chris

 

 

Sep 23, 2009 at 6:06 AM

Well, I suspected such kind of behaviour... the params collection is interpreted as new object each time the method gets called and so the caching handler creates a new key for each call :(

Thank you.

Sep 23, 2009 at 6:17 AM
Edited Sep 23, 2009 at 6:17 AM

I just tested it again with a global member int[] so that the same reference is used for each call and it is cached correctly... so Chris your theory looks pretty confirmed :)

Thx again.