C#WebClient禁用缓存

时间:2010-09-28 11:08:39

标签: c# caching webclient

美好的一天。

我在我的C#应用​​程序中使用WebClient类,以便每分钟下载相同的文件,然后应用程序执行简单的检查以查看文件是否已更改,以及是否确实有它的东西。

好了,因为WebClient缓存系统每分钟都会下载这个文件缓存文件,而不是再次下载文件,只是简单地从缓存中获取文件,这样就会检查文件是否正确下载是新的。

所以我想知道如何禁用WebClient类的缓存系统。

我试过了。

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

我也尝试了标题。

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

没有用。那么我该如何禁用缓存呢?

感谢。

修改

我还尝试了以下CacheLevelsNoCacheNoStoreBypassCacheReload。没有效果,但是如果我重新启动计算机,缓存似乎被清除,但我不能每次都重新启动计算机。

  

面对最近的活动更新(8 Set 2012)

     

标记为已接受的answer解决了我的问题。说实话,我用过   套接字下载文件,解决了我的问题。基本上是一个GET   请求所需的文件,我不会详细介绍如何操作,   因为我相信你可以在SO上找到很多“怎么样”   为了自己做同样的事情。虽然这并不意味着我的解决方案对你来说也是最好的,但我的第一个建议是阅读其他答案,看看是否有用。

     

嗯,无论如何,由于这个问题已经看到了最近的一些活动,我考虑添加这个更新,以包括一些我认为应该被那些面临类似问题的人考虑的提示或想法   他们可以想到的一切,并确定问题不在于   用他们的代码。 可能是大多数情况下的代码,但有时候我们只是看不到它,只需要散步几分钟后再回来,你可能会看到它是空白范围,就像它是最首先是明显的事情。

     

无论哪种方式,如果您确定,那么在这种情况下,我建议检查天气,您的请求通过其他具有缓存功能的设备(计算机,路由器,代理,...),直到它到达预定目的地。

     

考虑到大多数请求都是通过之前提到的一些此类设备,更多   通常是路由器,除非你直接连接到   通过您的服务提供商上网   网络

     

有一段时间我自己的路由器正在缓存文件,奇怪我知道,但事实就是如此,每当我重新启动它或直接连接到Internet时,我的缓存问题就消失了。并且没有任何其他设备连接到路由器可以被指责,只有计算机和路由器。

     

顺便说一下,一般的建议,虽然它主要适用于那些在公司开发计算机而不是自己的计算机上工作的人。可以通过任何更改您的开发计算机运行各种缓存服务?这是可能的。

     

此外,请考虑许多高端网站或服务使用Content Delivery Networks(CDN),并视CDN提供商而定,   无论何时更新或更改文件,都需要一些时间   变化反映在整个网络中。因此它可能是   可能你因为要求提供可能的文件而运气不好   在更新的中间,和最近的CDN服务器   尚未完成更新。

     

无论如何,特别是如果你总是一遍又一遍地请求同一个文件,或者你找不到问题所在,那么如果可能的话,我建议你重新考虑你的方法在一次又一次地请求相同的文件,而是考虑构建一个简单的Web Service,以满足您首先考虑满足此类文件的需求。

     

如果您正在考虑此类选项,我认为您可能会更轻松地根据自己的需要构建REST样式Web API

     

我希望这个更新在某种程度上对你有用,肯定会在我回来的时候。祝你的编码工作顺利。

12 个答案:

答案 0 :(得分:27)

每次下载文件时,您都可以尝试将一些随机数附加到您的网址作为查询字符串的一部分。这确保了每次都是唯一的URL。

前 -

Random random = new Random();
string url = originalUrl + "?random=" + random.Next().ToString();
webclient.DownloadFile(url, downloadedfileurl);

答案 1 :(得分:12)

从上面我猜想你在其他地方有问题。你能在服务器端记录http请求吗?当你改变一些随机种子参数时会得到什么?

也许SERVER缓存该文件(如果日志显示该请求确实是每分钟触发一次。

您使用ISA还是SQUID?

您的请求的http响应代码是什么?

我知道回答答案可能不受欢迎,但评论不允许我这么多文字:)

编辑:

无论如何,使用HttpRequest对象代替WebClient,并希望(如果您将疑虑置于WebClient),一切都将得到解决。如果它没有用HttpRequest解决,那么问题确实存在于其他地方。

进一步完善:

更低:How do I Create an HTTP Request Manually in .Net?

这是纯粹的套接字,如果问题仍然存在,那么打开一个新问题并将其标记为WTF:)

答案 2 :(得分:10)

尝试NoCacheNoStore

  

永远不会通过使用缓存中的资源来满足请求,也不会缓存资源。如果资源存在于本地缓存中,则会将其删除。此策略级别向中间缓存指示应删除资源。在HTTP缓存协议中,这是使用no-cache缓存控制指令实现的。

client.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore); 

答案 3 :(得分:7)

在某些情况下,网络调试软件可能会导致此问题。要确保您的网址没有被缓存,您可以附加一个随机数作为最后一个参数,以使网址唯一。在大多数情况下,这个随机参数被服务器忽略(它尝试读取作为名称值对发送的参数)。

实施例: http://www.someserver.com/?param1=val1&ThisIsRandom=RandomValue

其中ThisIsRandom = RandomValue是添加的新参数。

答案 4 :(得分:1)

我猜你必须使用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;
    }

答案 5 :(得分:1)

client.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);

应该有效。只需确保清除缓存并删除Internet Explorer 中的任何临时下载文件,然后将代码运行为System.Net,并且IE都使用相同的缓存。

答案 6 :(得分:1)

我在使用webClient时遇到了类似的问题,在切换到使用webRequest后也出现了。我发现的是套接字被重用并导致各种服务器/网络端缓存(在我的情况下,负载均衡器在使用https方面尤其成问题)。解决这个问题的方法是在webrequest对象中禁用keepalive和可能的管道,如下所示,这会强制为每个请求添加一个新套接字:

#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() }

答案 7 :(得分:1)

使用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中,直到我包含最后两个中的一个或两个,它才对我有效。

答案 8 :(得分:1)

这里的所有方法似乎都无法解决问题: 如果网页已经可以访问并且现在已从服务器中删除,则HttpWebResponse.GetResponse()方法将为您提供对以&#34开头的缓存副本的响应;在经过一段足够的时间之后,或者您重新启动计算机,它不会触发404页面找不到错误的预期异常,你现在根本不知道网页现在根本不存在。

我尝试了一切:

  • 设置标题(&#34; Cache-Control&#34;,&#34; no-cache&#34;)
  • 设置&#34; request.CachePolicy&#34;到&#34; noCachePolicy&#34;
  • 删除IE tem / history文件。
  • 使用没有路由器的有线互联网..........不工作!

幸运的是,如果网页更改了内容,HttpWebResponse.GetResponse()将为您提供一个新页面以反映更改。

答案 9 :(得分:0)

检查您是否受到费率限制!我从nginx服务器上得到了这个:

403 Forbidden

超出限额,请在24小时内再试一次。

这是我正在使用的程序(C#)

using System;
using System.IO;
using System.Net;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DownloadFile();
            Console.ReadLine();
        }

        public static void DownloadFile()
        {
            var downloadedDatabaseFile = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
            Console.WriteLine(downloadedDatabaseFile);

            var client = new WebClient();
            client.DownloadProgressChanged += (sender, args) =>
            {
                Console.WriteLine("{0} of {1} {2}%", args.BytesReceived, args.TotalBytesToReceive, args.ProgressPercentage);
            };

            client.DownloadFileCompleted += (sender, args) =>
            {
                Console.WriteLine("Download file complete");

                if (args.Error != null)
                {
                    Console.WriteLine(args.Error.Message);
                }
            };

            client.DownloadFileAsync(new Uri("http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dats.gz"), downloadedDatabaseFile);
        }
    }
}

控制台打印出来:

C:\Users\jake.scott.WIN-J8OUFV09HQ8\AppData\Local\Temp\2\tmp7CA.tmp
Download file complete
The remote server returned an error: (403) Forbidden.

答案 10 :(得分:0)

因为我使用以下内容:

wclient.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
wclient.Headers.Add("Cache-Control", "no-cache");

我再也没有缓存文件了。

我还添加了我发现的这个函数,在每次调用之前删除IE临时文件:

private void del_IE_files()
{
    string path = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);
    //for deleting files

    System.IO.DirectoryInfo DInfo = new DirectoryInfo(path);
    FileAttributes Attr = DInfo.Attributes;
    DInfo.Attributes = FileAttributes.Normal;

    foreach (FileInfo file in DInfo.GetFiles())
    {
        file.Delete();
    }

    foreach (DirectoryInfo dir in DInfo.GetDirectories())
    {
        try
        {
            dir.Delete(true); //delete subdirectories and files
        }
        catch
        {

        }
    }
}

答案 11 :(得分:0)

如果您有访问网络服务器的权限,请打开Internet Explorer,转到

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

清除浏览器缓存,瞧,它会起作用!