WebRequest не делает кэшированные элементы доступными в том же процессе - PullRequest
4 голосов
/ 04 октября 2010

Мы наблюдаем странное поведение, когда вещи, которые кэшируются (в кэше IE / wininet) в результате использования API WebRequest, недоступны из кэша, пока не будет создан новый процесс.

Рассмотрим следующий код:

using System;
using System.IO;
using System.Net;
using System.Net.Cache;
using System.Threading;

namespace HttpCachingTest {
    class Program {
        static void Main(string[] args) {
            MakeRequest();
            Thread.Sleep(1000);
            MakeRequest();
        }

        private static void MakeRequest() {
            var request = (HttpWebRequest)WebRequest.Create("http://a0.twimg.com/a/1286210883/images/twitter_logo_header.png");
            request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Default);

            var response = (HttpWebResponse)request.GetResponse();
            Console.WriteLine(String.Format("IsFromCache: {0}, ContentLength: {1}", response.IsFromCache, response.ContentLength));

            using (var fileStream = File.OpenWrite("test.jpg")) {
                response.GetResponseStream().CopyTo(fileStream);
            }
        }
    }
}

Поведение, которое мы видим, заключается в том, что для второго запроса IsFromCache имеет значение false. Однако, если мы запустим приложение во второй раз, то IsFromCache верен. Это подразумевает, что вещи правильно кэшируются, но те вещи, которые только что были кэшированы, недоступны текущему процессу, что имеет мало смысла.

Может кто-нибудь объяснить это поведение и узнать, как его можно исправить, чтобы кешированные элементы могли сразу попасть?

1 Ответ

5 голосов
/ 05 октября 2010

Вы не утилизируете ни HttpWebResponse, ни поток, возвращенный GetResponseStream(). Следовательно, кажется, что он не завершил обработку запроса, и полученные данные не могут быть безопасно сохранены в кеше, так как это может быть не полная сущность. Когда ваш процесс завершится, финализаторы исправят это, поэтому он будет в кеше при следующем запуске.

Утилизируйте ваши одноразовые объекты правильно, и поведение кэширования будет таким, как ожидалось.

...