web-dev-qa-db-ja.com

C#WebClientはキャッシュを無効にします

良い一日。

私はC#アプリケーションでWebClientクラスを使用して毎分同じファイルをダウンロードします。その後、アプリケーションはファイルが変更されたかどうかを確認するために簡単なチェックを実行します。それ。

このファイルは毎分ダウンロードされるので、WebClientキャッシングシステムはファイルをキャッシュし、ファイルを再度ダウンロードするのではなく、単にキャッシュから取得するだけです。これにより、ダウンロードしたファイルが新着。

だから、WebClientクラスのキャッシュシステムを無効にする方法を知りたいです。

私はもう試した。

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

ヘッダーも試しました。

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

うまくいきませんでした。キャッシュを無効にするにはどうすればよいですか?

ありがとう。

[〜#〜] edit [〜#〜]

次のCacheLevelsも試してみました:NoCacheNoStoreBypassCacheReload。効果はありませんが、コンピューターを再起動するとキャッシュがクリアされたように見えますが、毎回コンピューターを再起動することはできません。

最近の活動に直面して更新(8 Set 2012)

answer が承認済みとしてマークされると、問題が解決しました。簡単に言うと、Socketsを使用してファイルをダウンロードし、問題を解決しました。基本的に、目的のファイルのGETリクエストです。ここでSO inで多くの "方法"を見つけることができると確信しているので、その方法については詳しく説明しません。これは自分のソリューションがあなたにとって最適であることを意味するものではありませんが、私の最初のアドバイスは、他の答えを読んで、役に立つものがあるかどうかを確認することです。

とにかく、この質問には最近の活動が見られたので、この更新プログラムを追加して、考えられるすべてを試した同様の問題に直面している人が考慮すべきヒントやアイデアを含めることを考えました。コードに嘘をつきます。 ほとんどの場合、コードである可能性が高いですが、時々、私たちはそれをまったく見ずに、歩いて数分後に戻ってくるだけで、おそらくあなたはそれが空白であることを見るでしょうそもそもそれが最も明白なもののような範囲。

どちらにしても、確かな場合は、その場合、リクエストが目的の宛先に到達するまで、リクエストがキャッシュ機能を備えた他のデバイス(コンピューター、ルーター、プロキシなど)を通過するかどうかを確認することをお勧めします。

もちろん、サービスプロバイダーネットワーク経由でインターネットに直接接続されていない限り、ほとんどの要求は前述のようなデバイス、より一般的なルーターを経由することを考慮してください。

かつて私自身のルーターがファイルをキャッシュしていたのは奇妙なことですが、再起動したり、インターネットに直接接続したりすると、キャッシュの問題はなくなりました。そして、非難できるルーターに接続された他のデバイスはなく、コンピューターとルーターだけがありました。

ちなみに、一般的なアドバイスですが、ほとんどの場合、自分の会社ではなく会社の開発コンピューターで作業する人に適用されます。変更により、開発コンピューターでさまざまなキャッシュサービスを実行できますか?可能です。

さらに、多くのハイエンドWebサイトまたはサービスは Content Delivery Networks (CDN)を使用し、CDNプロバイダーによっては、ファイルが更新または変更されるたびに、そのような変更が反映されるまでに時間がかかることを考慮してくださいネットワーク全体。そのため、更新中のファイルを要求するという不運があり、最も近いCDNサーバーが更新を完了していない可能性があります。

いずれの場合でも、特に同じファイルを何度も何度もリクエストしている場合、または可能であれば問題の場所が見つからない場合、同じファイルを何度もリクエストする際のアプローチを再検討し、代わりに単純な Webサービス を構築することを検討することをお勧めします。 。

そして、あなたがそのようなオプションを検討しているなら、おそらくあなたは [〜#〜] rest [〜#〜] スタイル Web API ニーズ。

このアップデートが何らかの形であなたの役に立つことを望んでいます。コーディングの努力をお祈りします。

27
Fábio Antunes

上記から、他のどこかに問題があると思います。サーバー側でhttpリクエストを記録できますか?ランダムシードパラメータを変更すると何が得られますか?

SERVERがファイルをキャッシュする場合があります(ログが毎分本当にリクエストがトリガーされたことを示している場合)。

ISAまたはSQUIDを使用しますか?

リクエストのhttp応答コードとは何ですか?

回答で回答することは一般的ではないかもしれないことは知っていますが、コメントではこれだけのテキストは許可されません:)

編集:

とにかく、HttpRequestの代わりにWebClientオブジェクトを使用し、できれば(WebClientに疑問がある場合)すべてが解決されることを願っています。 HttpRequestで解決しなかった場合、問題は本当にIS他のどこかにあります。

さらなる改良:

さらに下に移動: 。NetでHTTP要求を手動で作成する方法

これは純粋なソケットであり、問​​題が解決しない場合は、新しい質問を開いてWTFというタグを付けます:)

12

ファイルをダウンロードするたびに、クエリ文字列の一部としてURLに乱数を追加してみてください。これにより、毎回URLが一意になります。

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

NoCacheNoStore を試してください:

キャッシュのリソースを使用してリクエストを処理することはなく、リソースをキャッシュしません。リソースがローカルキャッシュに存在する場合、削除されます。このポリシーレベルは、リソースを削除する必要があることを中間キャッシュに示します。 HTTPキャッシュプロトコルでは、これはキャッシュなしキャッシュ制御ディレクティブを使用して実現されます。

client.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore); 
10
KMån

一部のシナリオでは、ネットワークデバッグソフトウェアがこの問題を引き起こす可能性があります。 URLがキャッシュされないようにするには、最後のパラメーターとして乱数を追加して、URLを一意にすることができます。ほとんどの場合、このランダムパラメーターはサーバー(名前と値のペアとして送信されたパラメーターを読み取ろうとするサーバー)によって無視されます。

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

ThisIsRandom = RandomValueは追加された新しいパラメーターです。

7
ivymike

ここのすべてのメソッドは問題を解決できないようです:Webページがアクセス可能になり、サーバーから削除された場合、HttpWebResponse.GetResponse()メソッドは、「十分な期間の前に」時間が経過した場合、またはコンピューターを再起動した場合、404ページが見つからないというエラーに対して予期される例外がトリガーされず、Webページが現在まったく存在しないことがわかりません。

私はすべてを試しました:

  • ( "Cache-Control"、 "no-cache")のようなヘッダーを設定します
  • 「request.CachePolicy」を「noCachePolicy」に設定します
  • 削除IE tem/historyファイル。
  • ルーターなしで有線インターネットを使用する..........動作しません!

幸いなことに、Webページのコンテンツが変更された場合、HttpWebResponse.GetResponse()は変更を反映する新しいページを提供します。

1
lbhl

WebClientを使用するPowerShellで同様の問題が発生しました。webClientはwebRequestを使用するように切り替えた後にも存在していました。私が発見したことは、ソケットが再利用され、あらゆる種類のサーバー/ネットワーク側のキャッシュが発生することです(私の場合、ロードバランサーが邪魔になり、特にhttpsで問題が発生します)。これを回避する方法は、キープアライブを無効にし、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
user856684
client.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);

動作するはずです。キャッシュをクリアし、Internet Explorerで一時的にダウンロードしたファイルを削除してくださいbeforeとしてコードを実行しますSystem.NetとIEは両方とも同じキャッシュを使用します。

1
Darin Dimitrov

Webclientではなくwebrequest/webresponseを使用する必要があると思います

    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;
    }
1
Thakur

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では、最後の2つのうちの1つまたは両方を含めるまで機能しませんでした。

1
Daniel

私は次を使用しているので:

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
        {

        }
    }
}
0
error

レート制限されていないことを確認してください!私はnginxサーバーからこれを取り戻していました:

403禁止します

これが私が使っていたプログラムです(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.
0
superlogical

Webサーバーにアクセスできる場合は、Internet Explorerを開いて

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

ブラウザのキャッシュをクリアして、出来上がります。

0
efkah