私は最近サービスに変換したC#アプリケーションを持っています。通常の操作の一環として、次のコードを使用してCRを経由してPDFの請求書を作成します。Crystal Reportsはガベージコレクションにもかかわらずジョブの制限に達します
foreach (string docentry in proformaDocs)
using (ReportDocument prodoc = new ReportDocument()) {
string filename = outputFolder + docentry + ".pdf";
prodoc.Load(/* .rpt file */);
prodoc.SetParameterValue(0, docentry);
prodoc.SetParameterValue(1, 17);
prodoc.SetDatabaseLogon(/* login data */);
prodoc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat,
filename);
prodoc.Close();
prodoc.Dispose();
}
foreach (string docentry in invoiceDocs)
using (ReportDocument invdoc = new ReportDocument()) {
string filename = differentOutputFolder + docentry + ".pdf";
invdoc.Load(/* different .rpt file */);
invdoc.SetParameterValue(0, docentry);
invdoc.SetParameterValue(1, 13);
invdoc.SetDatabaseLogon(/* login data */);
invdoc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat,
filename);
invdoc.Close();
invdoc.Dispose();
}
GC.Collect();
問題は、ほとんどの2分ごとに実行される上記のコードで実行時の約3~4時間、負荷(後に、あります)操作では、明示的にレポートオブジェクトを廃棄しても、処理ジョブの制限に達します。しかし、サービスを実行したままにして、同じアプリケーションの非サービスインスタンスを起動すると、サービスがまだジョブ制限例外をスローしている間も、そのアプリケーションは正常に実行されます。非サービスインスタンスが処理を担当しているので、サービスは現時点では何もしませんが、サービスが手動で停止してサービスを再開するまでエラーを再送信します。その時点でエラーは消え去りますさらに3〜4時間。
すべての単一のレポートオブジェクトを処理したらすぐに処理し、処理と廃棄の各ラウンド後にガベージコレクションを呼び出すと、どのようにジョブの制限にぶつかるのですか?ジョブの制限に達すると、同じコードのパラレルインスタンスはどのように影響を受けませんか?
更新:私は問題を追跡することができましたが、それはCRではないことがわかりました。これは、スレッドをフリーズ呼び出し、何らかの理由で
public Company GetSAP(string name) {
Database db; //wrapper class
SAP.TryGetValue(name, out db); //fetching from the Dictionary
return db.SAP; //Company object in the wrapper class
}
が、タイマーは、サービスの正常な動作を開始:私はこれで、辞書に保存されているデータベースのラッパークラス内でフェッチされたSAP社のオブジェクトからCRのデータベース・ログイン資格証明を取ります自然にそれが完了するのを待たずに、別のスレッドを起動します。これは、これを呼び出すとフリーズします。これは、固定されたスレッドの数がジョブの制限に達するまで維持されます。その時点で、まだ制限されたスレッドがジョブの制限を満たすため、新しいスレッドごとに例外がスローされます。あるスレッドがまだ実行中で、上記の関数を呼び出すとアプリケーションが凍結した場合、新しいスレッドを起動しないようにチェックを入れました。
上記のreturn db.SAP
オブジェクトのゲッターは、return
以外の文字は何も含まれていません。
'GC.Collect'を明示的に呼び出さないでください。それはコードのにおいであり、99で必要とされません。(9)%の場合。また 'ReportDocument'オブジェクトに対して' close'と 'Dispose'を呼び出す必要はありません。これは' using'ステートメントのために自動的に行われるからです。 – dymanoid
多くのレポート文書を読み込んだらLOHフラグメンテーションのように思えます。 「ヒット処理の仕事の制限」とはどういう意味ですか?どんな種類の例外がありますか?私はよくCRを知らない。 –
@ KonradKokosa 「レポートの読み込みに失敗しました」というメッセージが表示され、InteropServices.COMExceptionの内部例外として「システム管理者によって設定された最大レポート処理ジョブ制限に達しました」というメッセージが表示されます。デフォルトでは75個の同時ジョブのグローバルな制限がありますが、一度に多数のジョブを処理することはなく、上記のように制限に達するずっと前にガベージコレクションを行う必要があります。それでなぜ私はこのことに困惑しているのですか? – amitakartok