ManagementObjectSearcher を使っていて、 WMI の Win32_NTLogEvent を取得しようとしたときに、フィルタ条件に該当するデータが極端に多いときに クォータ違反です というエラーが発生するようになりました。エラーが発生した環境は、次のとおり。

  • Windows Server 2003 R2
  • .NET 3.5 SP1

エラーが発生する場合のKBは以下のようなものがあるようですが、私のケースでは今回は関係ないみたいでした。

大きな WMI 通知クエリによりクォータ違反が発生する場合がある
http://support.microsoft.com/?id=828653

1. コードで解決

結論から述べると、既定では true になっているEnumerationOptions.Rewindable プロパティ を false にして回避しました。Rewindable は 巻き戻して読み取りを行うばあはtrueにする必要があるのですが、このプロパティが true だと、クエリを出しているサーバのメモリがかなり使用されます。といっても300MBもいかないのですが、それ以上メモリが使用されなくなります。

EnumerationOptions は、ManagementObjectSearcher.Options プロパティから参照できます。

あまり効果はありませんでしたが、EnumerationOptions.BlockSize も 大きな値(既定値1) にしました。この値を大きくすると結果サイズが大きい単位で取得できるのでネットワークを効率的に使用できるそうです。

2. そのほかの解決方法かもしれなこと

WMI Provider が使用できるメモリを変更する方法。WMI Provider は Vista 以前では最大でも 128MB しか使用できないので、この値を大きくすると同様のクォータ違反問題が解決できる可能性があります。詳細は下のリンクを参照

- Memory and Handle Quotas in the WMI Provider Service
http://blogs.technet.com/askperf/archive/2008/09/16/memory-and-handle-quotas-in-the-wmi-provider-service.aspx

3.まとめ

説明は以上です、 Rewindable は false にすることで、ほとんどメモリを使用しなくなり、パフォーマンスも向上するので、読み取りを1回のみ行う場合はかなり効果的です。

おまけで、 WMI のチップス情報。

Troubleshooting and Tips
http://technet.microsoft.com/ja-jp/library/ee692772(en-us).aspx