Seems indeed a cache problem. Looking at the implementation of the Exists method, we can see that it internally creates a new instance of an SPSite object to check if it exists.
SPSite theSite = null;
try
{
theSite = new SPSite(uri.OriginalString);
}
catch (FileNotFoundException)
{
// do nothing, just leave the instance null. The rest of the code will detect this.
}
After that, some of the property of the instance are evaluated (HostHeaderIsSiteName
and some of the url properties).
Problem is that the SPSite constructor utilize an internal cache to set the object properties. Most of the calls seems to come up to the SPSiteCache class and some of its methods (for example: SPSiteCache.LookupHostHeaderSite
) => this would mean that if the site is referenced in the cache we can get invalid results.
After some time lost on MSDN I have found some reference to a cache clear method.
SPSite.InvalidateCacheEntry(new Uri(siteCollectionUrl), Guid.Empty);
It seems that this method just calls the SPSiteCache class internally
public static bool InvalidateCacheEntry(Uri uri, Guid siteId)
{
return SPSiteCache.InvalidateCacheEntry(uri, siteId);
}
I have used this instruction just before the call to Exist to ensure a valid result. That way, the problem was resolved.
Notes:
- I don't know what is the resource cost of this solution. If performance are critical, please ensure that clearing the cache doesn't bring a performance hit.
- someone sugested that the problem can be related to the gradual site deletion job. I don't belive it is, but you never know. As I already said, the timer job could as well call the istruction above internally. That said, by calling the InvalidateCacheEntry method I never needed to manually run the job - and I am creating sites pretty fast. Also consider that running a timer job could be problematic in some context - so give the above method a try if you are experiencing the same problem.