C # WebClient отключить кеш - PullRequest
       32

C # WebClient отключить кеш

27 голосов
/ 28 сентября 2010

Добрый день.

Я использую класс WebClient в своем приложении C # для загрузки одного и того же файла каждую минуту, а затем приложение выполняет простую проверку, чтобы проверить, был ли файлизменился, и если он что-то с этим сделает.

Хорошо, поскольку этот файл загружается каждую минуту, система кэширования WebClient кэширует файл, и не загружает файл снова, просто получает его из кэшаи это мешает проверить, является ли загруженный файл новым.

Так что я хотел бы знать, как отключить систему кэширования класса WebClient.

Я имеюпробовал.

Client.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);

Я также пробовал заголовки.

WebClient.Headers.Add("Cache-Control", "no-cache");

Также не работал.Так как же я могу отключить кэш для хорошего?

Спасибо.

РЕДАКТИРОВАТЬ

Я также попробовал следующее CacheLevels: NoCacheNoStore,BypassCache, Reload.Однако безрезультатно, если я перезагружаю свой компьютер, кэш, кажется, очищается, но я не могу каждый раз перезагружать компьютер.

ОБНОВЛЕНИЕ перед лицом недавних действий (8 Set 2012)

Ответ , помеченный как принятый, решил мою проблему.Проще говоря, я использовал Sockets для загрузки файла, и это решило мою проблему.В основном это GET-запрос для нужного файла, я не буду вдаваться в подробности о том, как это сделать, потому что я уверен, что вы можете найти множество «как» прямо здесь, на SO, чтобы сделать то же самое самостоятельно.Хотя это не означает, что мое решение также является лучшим для вас, мой первый совет - прочитать другие ответы и посмотреть, будут ли они полезны.

Ну, в любом случае, поскольку эти вопросы стали свидетелями недавней активности, яподумал о том, чтобы добавить это обновление, чтобы включить некоторые подсказки или идеи, которые, я думаю, должны быть учтены теми, кто сталкивается с похожими проблемами, которые перепробовали все, что могли придумать, и уверены, что проблема не в их коде. Скорее всего, это код для большинства случаев, но иногда мы просто не видим его, просто прогуляйтесь и вернитесь через несколько минут, и вы, вероятно, увидите его в упор, как это было больше всего.Во-первых, очевидная вещь.

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

Учтите, что большинство запросов проходит через некоторые из упомянутых выше устройств, чаще всего через маршрутизаторы, если, конечно, вы напрямую не подключены к Интернету через сеть своего поставщика услуг.

За один раз мойсобственный роутер кэшировал файл, странно, я знаю, но это было так, когда я перезагружал его или подключался напрямую к Интернету, моя проблема с кэшированием исчезала.И нет, не было другого устройства, подключенного к маршрутизатору, который можно обвинить, только компьютер и маршрутизатор.

И, кстати, общий совет, хотя он в основном относится к тем, кто работает в их компанииразработка компьютеров вместо собственных.Могут ли какие-либо изменения на вашем компьютере разработки работать с какой-либо службой кэширования?Это возможно.

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

В любом случае , особенно если вы всегда запрашиваете один и тот же файл снова и снова или если вы не можете найти, в чем заключается проблема, тогда, если возможно, я советую вам пересмотреть свой подход взапрашивая один и тот же файл раз за разом, и вместо этого изучите создание простого веб-сервиса , чтобы удовлетворить потребности, которые вы сначала подумали об удовлетворении такого файла.

А еслирассматривают такой вариант, я думаю, вам, вероятно, будет проще создать REST Style Web API для собственных нужд.

Надеюсь, это обновление будет полезно вкаким-то образом, конечно, это будет для меня, пока я вернусь.Желаем удачи в ваших усилиях по кодированию.

Ответы [ 12 ]

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

Вы можете попытаться добавить случайное число к вашему URL как часть строки запроса при каждой загрузке файла.Это гарантирует, что URL уникальны каждый раз.

Для бывших

Random random = new Random();
string url = originalUrl + "?random=" + random.Next().ToString();
webclient.DownloadFile(url, downloadedfileurl);
12 голосов
/ 06 октября 2010

Исходя из вышесказанного, я думаю, что у вас есть проблемы где-то еще.Можете ли вы регистрировать HTTP-запросы на стороне сервера?Что вы получаете, когда вы изменяете какой-то случайный начальный параметр?

Возможно, SERVER кэширует файл (если журнал показывает, что запрос действительно запускается каждую минуту.

Используете ли вы ISA или SQUID?

Что такое http код ответа на ваш запрос?

Я знаю, что ответы с ответами могут быть не популярны, но комментарии не позволяют мне так много текста:)

РЕДАКТИРОВАТЬ:

В любом случае, используйте HttpRequest объект вместо WebClient, и, надеюсь, (если вы сомневаетесь в WebClient) все будет решено.Если это не было решено с помощью HttpRequest, то проблема действительно в другом месте.

Дальнейшее уточнение:

Идите еще ниже: Как создать запрос HTTP вручную.Net?

Это чистые сокеты, и если проблема не устранена, откройте новый вопрос и присвойте ему тег WTF:)

10 голосов
/ 28 сентября 2010

Попробуйте NoCacheNoStore:

Никогда не удовлетворяет запрос, используя ресурсы из кеша и не кеширует ресурсы. Если ресурс присутствует в локальном кэше, он удаляется. Этот уровень политики указывает промежуточным кэшам, что они должны удалить ресурс. В протоколе кэширования HTTP это достигается с помощью директивы управления кэшированием без кэша.

client.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore); 
7 голосов
/ 05 октября 2010

В некоторых случаях этой проблемой может быть программное обеспечение отладки сети.Чтобы убедиться, что ваш URL не кэшируется, вы можете добавить случайное число в качестве последнего параметра, чтобы сделать URL уникальным.Этот случайный параметр в большинстве случаев игнорируется серверами (которые пытаются прочитать параметры, отправленные в виде пар имя-значение).

Пример: http://www.someserver.com/?param1=val1&ThisIsRandom=RandomValue

Где ThisIsRandom = RandomValue - добавленный новый параметр.

1 голос
/ 05 февраля 2016

Все методы здесь не могут решить проблему: Если веб-страница когда-либо была доступна и теперь удалена с сервера, метод HttpWebResponse.GetResponse () даст вам ответ для кэшированной копии, начинающийся с «До истечения достаточного времени или перезагрузки компьютера, НЕ вызывает ожидаемое исключение для ошибки 404 страница не найдена, вы не можете знать, что веб-страница теперь вообще не закрывается.

Я попробовал все:

  • Установить заголовок как («Cache-Control», «no-cache»)
  • Установите для "request.CachePolicy" значение "noCachePolicy"
  • Удалить файлы IE tem / history.
  • Использовать проводной интернет без роутера .......... НЕ РАБОТАЕТ!

К счастью, если веб-страница изменила свое содержание, HttpWebResponse.GetResponse() даст вам новую страницу, чтобы отразить это изменение.

1 голос
/ 11 сентября 2014

Использование HTTPRequest, безусловно, правильный ответ для вашей проблемы.Однако, если вы хотите, чтобы ваш объект WebBrowser / WebClient не использовал кэшированные страницы, вы должны включить не только "no-cache", но и все эти заголовки:

<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Cache-control" content="no-store">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="-1">

В IE11 это не сработало для меняпока я не включил один или оба из последних двух.

1 голос
/ 21 июля 2011

У меня была похожая проблема с powershell при использовании webClient, которая также присутствовала после переключения на использование webRequest. Я обнаружил, что сокет используется повторно, и это вызывает все виды кэширования на стороне сервера / сети (и в моем случае балансировщик нагрузки оказался слишком проблематичным с https). Чтобы обойти это, нужно отключить keepalive и, возможно, конвейеризацию в объекте webrequest, как показано ниже, что приведет к созданию нового сокета для каждого запроса:

#Define Funcs Function httpRequest {
     param([string]$myurl)
     $r = [System.Net.WebRequest]::Create($myurl)
     $r.keepalive = 0
     $sr = new-object System.IO.StreamReader (($r.GetResponse()).GetResponseStream())
     $sr.ReadToEnd() }
1 голос
/ 04 октября 2010
client.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);

Должно работать. Просто убедитесь, что вы очистили кеш и удалили все временные загруженные файлы в Internet Explorer перед тем, как запустит код, так как System.Net и IE оба используют один и тот же кеш.

1 голос
/ 30 сентября 2010

Думаю, вам придется использовать webrequest / webresponse, а не webclient

    WebRequest request = WebRequest.Create(uri);
     // Define a cache policy for this request only. 
     HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
     request.CachePolicy = noCachePolicy;
     WebResponse response = request.GetResponse();

//below is the function for downloading the file

   public static int DownloadFile(String remoteFilename,
                           String localFilename)
    {
        // Function will return the number of bytes processed
        // to the caller. Initialize to 0 here.
        int bytesProcessed = 0;

        // Assign values to these objects here so that they can
        // be referenced in the finally block
        Stream remoteStream = null;
        Stream localStream = null;
        WebResponse response = null;

        // Use a try/catch/finally block as both the WebRequest and Stream
        // classes throw exceptions upon error
        try
        {
            // Create a request for the specified remote file name
            WebRequest request = WebRequest.Create(remoteFilename);
            // Define a cache policy for this request only. 
            HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
            request.CachePolicy = noCachePolicy;
            if (request != null)
            {
                // Send the request to the server and retrieve the
                // WebResponse object 
                response = request.GetResponse();

                if (response != null)
                {
                    if (response.IsFromCache)
                        //do what you want

                    // Once the WebResponse object has been retrieved,
                    // get the stream object associated with the response's data
                    remoteStream = response.GetResponseStream();

                    // Create the local file
                    localStream = File.Create(localFilename);

                    // Allocate a 1k buffer
                    byte[] buffer = new byte[1024];
                    int bytesRead;

                    // Simple do/while loop to read from stream until
                    // no bytes are returned
                    do
                    {
                        // Read data (up to 1k) from the stream
                        bytesRead = remoteStream.Read(buffer, 0, buffer.Length);

                        // Write the data to the local file
                        localStream.Write(buffer, 0, bytesRead);

                        // Increment total bytes processed
                        bytesProcessed += bytesRead;
                    } while (bytesRead > 0);
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {
            // Close the response and streams objects here 
            // to make sure they're closed even if an exception
            // is thrown at some point
            if (response != null) response.Close();
            if (remoteStream != null) remoteStream.Close();
            if (localStream != null) localStream.Close();
        }

        // Return total bytes processed to caller.
        return bytesProcessed;
    }
0 голосов
/ 28 августа 2015

Если у вас есть доступ к веб-серверу, откройте Internet Explorer и перейдите на

Internet Explorer -> Internet Options -> Browsing History "Settings" -> Temporary Internet Files "never"

Очистите кэш браузера и вуаля, он будет работать!

...