0

Linq2Sql を使用して、SSRS Web サービスで SSRS レポートのエクスポートを開始するために使用する ID のリストを取得します。クエリは約 200 項目を取得し、foreach ループを使用してそれらをループ処理します。

ID を含む List オブジェクトを、新しいスレッドで実行されるメソッドに渡します。

SSRS レポートの生成には非常に長い時間がかかるため、ワークロードが原因でサーバーの速度が低下すると、全体的な実行が20 分を超えてスレッドが終了することがありますが、例外はありません。

このユース ケースに一致する Linq2Sql DataContext のタイムアウト設定はありますか?その後、結果が利用できなくなり、foreach ループが終了しますか?

更新 1 (コード):

List<String> list = dc.ListaIDs().ToList<String>();
int count = 0;
foreach (var item in list)
{
    string FileName = "report_" + (++count).ToString() + ".pdf";
    LoggerUtility.Instance.log.Debug(String.Format("export => " + FileName));
    try
    {
        switch (ReportFormat)
        {
            case "PDF":
                risultato = ReportServiceImpl.WSReport("PDF", item);
                System.IO.File.WriteAllBytes(FileName, risultato.PDFResult);
                break;
            default:
                LoggerUtility.Instance.log.Warn("no format");
                break;
        }
    }
    catch (Exception ex)
    {
        LoggerUtility.Instance.log.Warn("error exporting => " + FileName, ex);
    }
}

更新 2:

(レポート WS 呼び出しを分離するために作成したカスタム ReportService クラスの) rs オブジェクトは、スレッドの同じスコープ内にありません。スレッドとして起動されたメソッドの外部で宣言およびインスタンス化され、メソッドと rs 宣言を含むクラスは MVC 3 コントローラーです。

ReportService クラスでは、呼び出しごとに新しい ReportExecutionService がインスタンス化されます (以前は、ReportExecution2005.asmx への Web 参照によって取得されていました)。

更新 3 (WS 呼び出しコードとコードの最初の部分の小さな更新):

コードをリファクタリングして、私ReportServiceImplのメソッドへの静的呼び出しを行い、Linq2Sql でタイムアウトを除外する可能性のある @JamieSee の応答で伝えられた内容を適用しました。これは ReportServiceImpl.WSReport の実際の実装です。20 分後、次の場所で例外なく停止しますresult = service.Render(...)

public static ReportResult WSReport(String format, string id)
{
    ReportResult _return = new ReportResult();
    ReportExecution.ReportExecutionService service = null;
    try
    {
        byte[] result;
        service = new ReportExecution.ReportExecutionService();

        String reportPath = @"/myReport";
        string historyID = null;

        service.UseDefaultCredentials = true;

        //load report
        ExecutionInfo execInfo = new ExecutionInfo();
        ExecutionHeader execHeader = new ExecutionHeader();

        service.ExecutionHeaderValue = execHeader;
        execInfo = service.LoadReport(reportPath, historyID);

        //set execution parameter
        ParameterValue[] parameters = new ParameterValue[1];
        parameters[0] = new ParameterValue() { Name = "id", Value = id };
        service.SetExecutionParameters(parameters, "it-IT");

        String SessionId = service.ExecutionHeaderValue.ExecutionID;

        //render report actually
        String deviceInfo = "";
        String extension;
        String mimetype;
        String encoding;
        GestioneVIP_Services.ReportExecution.Warning[] warnings;
        string[] streams;
        result = service.Render(format, deviceInfo, out extension, out mimetype, out encoding, out warnings, out streams);
        switch (format)
        {
            case Constants.EXCEL_FORMAT:
                _return.XLSResult = result;
                break;
            case Constants.PDF_FORMAT:
                _return.PDFResult = result;
                break;
            case Constants.HTML_FORMAT:
                _return.HTMLResult = result;
                break;
        }
    }
    catch (SoapException ex)
    {
        LoggerUtility.Instance.log.Error(String.Format("{0}/n{1}", ex.Message, ex.StackTrace));
    }
    catch (Exception ex)
    {
        LoggerUtility.Instance.log.Error(String.Format("{0}/n{1}", ex.Message, ex.StackTrace));
    }
    finally
    {
        if (service != null)
        {
            service.Dispose();
        }
    }
    return _return;
}
4

2 に答える 2

1

IEnumerable list = dc.ListaIDs();を変更してみてください。リストリストへ=dc.ListaIDs()。ToList();。これにより、foreachでの実行の遅延が回避され、Linqの問題なのか他の問題なのかがわかります。

于 2012-08-06T16:53:36.413 に答える
0

上記のコメントに記載されている複数のスレッド構成でテストし、この問題をさらに詳しく調べたところ、正しい答えが見つかったので、完全を期すためにここに報告します。

この微妙なタイムアウトの理由は、アプリケーション プールの[詳細設定]の [プロセス モデル]セクションの[アイドルタイムアウト]構成にあります。

デフォルト値は20 分です。

私がまだ理解していない何らかの理由で、Web レイヤーのアクティビティがない場合、いくつかのスレッドを起動する Web レイヤーから開始されたプロセスは Idle として扱われ、停止します。タスク マネージャーの [プロセス] タブでw3wp.exeプロセスの動作を追跡しても確認できます。 ThreadPool でキューに入れられたスレッド、またはこのプロセスによって直接起動されたスレッドはすべて、プロセスで終了します。

最後に、これは Linq2Sql 関連でも SRSS Web サービス関連でもなく、IIS プロセス モデル関連であると言えます。

于 2012-10-12T09:04:10.580 に答える