Share via


Download Cache

Alan has an excellent article on how HTTP assembly download works.

https://blogs.gotdotnet.com/alanshi/commentview.aspx/d3b8c7d9-b0c6-47fd-8ddf-20db971ba80d

In this article he talked about download cache as well as fusion's interaction with Internet Explorer, specifically, Urlmon.

Alan also discussed the download cache re-use of strongly named assemblies logic. Specifically,

<quote>

Strongly-named assemblies may be re-used from the download cache if the URL where Fusion will probe for the assembly matches the URL of the cached bits (and the assemblies have the same strong identity). If these conditions are met, no request is issued to the server. However, I caution again that you should not rely on this behaviour.

</quote>

The re-use logic is only applicable in Assembly.Load case. In Assembly.LoadFrom we don't re-use the cached bits.

Download cache has a default quota of 50M. Once the quota is reached, fusion will start removing bits in download cache in certain algorithm. The scavenging algorithm is implementation detail, and may change over time.

The re-use of strongly named assemblies logic draws quite a bit controversy. On one hand, people complains fusion does not cache bits agressive enough (since we do scavenging once the download cache's quota is reached). On the other hand, people complains fusion does not download the right bits when they update the assembly in server side.

Fusion will only re-use the cached bits if the assembly requested has the same assembly identity as the one in cache. If you change the assembly version of the requested assembly, we will not re-use the cached bits.

Occasionally, even if you change the assembly version of the assembly version, you may still get the cached bits. This is actually discussed in the last paragraph of Alan's article.

<quote>

Another point of interest is that because Fusion uses urlmon to download bits over http, even when Fusion does not re-use bits from the download cache, bits may be returned from the wininet cache without hitting the server. The usual "if-modified-since" logic is used to determine whether or not bits are returned from the wininet cache to Fusion, or whether they are re-downloaded from the server.

</quote>

An email from Alan explained more on the subject:

<quote>

In your case, since your assemblies are strongly-named, have a different version and different last-mod time on the server, you should not be bitten by any of the automatic caching Fusion does with its download cache (save the case where the http server is not returning the last mod time to us). The reason you have to close the application down and restart it is that wininet uses some sophisticated algorithms to determine whether or not it needs to go back to the server. In this case, since you replace the assembly immediately after having issued a request for the same URL, wininet decides there's no point going back to the server, and it gives Fusion back the same assembly (even though there are newer bits available).

In most cases, this heuristic is the right thing to do (think of the regular browsing experience). This optimization ends up hurting you, though, in the same way. If you want to not have to restart the app, you will need to force wininet to always go back to the server, or give it a hint that the cache bits are no good. One way to do this is to open IE, go to "tools | internet options | temporary internet files | settings" and choose "Every visit to the page" for "Check for newer versions of stored pages". The other way to do this is to configure IIS so that it sets a http expiry of "always" so that wininet knows the cached entry is no good (I don't know exactly how this is done, but it should be relatively easy to figure out from IIS documentation). Note you should not configure IIS with to return pragma nocache (or similar), as this will prevent Fusion from getting the assembly altogether.

</quote>

The re-use logic is meant for performance. It makes perfect sense for assemblies in http sites or UNC shares. But it almost make no sense for local disk assembly. In .Net framework 1.0 and v1.1, we do the re-use logic regardless of where the assembly is. In Whidbey beta2, I made a check in to disable the re-use logic if the assembly is in local disk.

The re-use logic is implemented purely in fusion. It does not go through Internet Explorer at all.