4

この質問は、まだ解決していない現在の問題から派生したものであることに注意してください。

WCF サービスが DataTable: OutOfMemoryException を返したときのエラーを解決するためのヘルプが必要です

エンドポイントが構成されている既存の WCF サービスとTransferMode.Buffered、接続が同じことを要求するクライアント アプリケーションがあります。

OperationContracts非常にマイナーな方法を除いて、簡単に変更できない確立されたメソッドです。たとえば、SQL クエリを受け取り、SQL実行から派生しStringた を返すメソッドがあります。DataTable

この方法を使用すると、非常に大きなテーブルで問題が発生します。大きな意味を持つインメモリ フットプリント。

実装TransferMode.Streamed(または同様のもの)を検討していますが、特定のメソッドだけでそれを行う方法を理解できないようです。

私の WCF サービスが起動し、唯一無二のエンドポイントが作成され、そのエンドポイントはBuffered. そのため、すべてか無かであると想定したいと思います。変更するとStreaming、すべての方法を大規模に作り直す必要がありOperationContractます。

このテーマに関連する SO の質問がいくつかありますが、直接的ではなく、必要な場所に実際に到達するような回答はありません。

何か不足していますか、それとも機能させることができますか?

私が修正する必要がある方法:(接続について知りたい場合は、参照されている質問を参照してください...それはたくさんのコードです)

WCF サービス コード:

[OperationContract]
DataTable readDataTable(out DbError dbError, String queryString, Boolean SchemaOnly);

public DataTable readDataTable(out DbError dbError, String queryString, Boolean SchemaOnly)
{
    DataTable dt = new DataTable("ReturnTable");
    dbError = new DbError();
    if (!String.IsNullOrEmpty(queryString))
    {
        try
        {
            command.CommandText = queryString.Replace(new String[] { "{{", "}}", ";;" }, new String[] { "{", "}", ";" });
            SqlDataReader reader = command.ExecuteReader(SchemaOnly ? CommandBehavior.SchemaOnly : CommandBehavior.Default);
            dt.Load(reader);
            reader.Close();
        }
        catch (Exception ex)
        {
            dbError.HasError = true;
            dbError.Error = ex.Message + "\n\n" + queryString;
        }
    }
    return dt;
}

それを使用するクライアント コード:

public DataTable readDataTable(String queryString, Boolean SchemaOnly)
{
    DbError dbError;
    DataTable dt = svcCon.readDataTable(out dbError, queryString, SchemaOnly);
    if (dbError.HasError)
    {
        if (_showErrors)
        ErrorHandler.Show(dbError.Error);
    }
    return dt;
}
4

1 に答える 1

2

これは大きな問題です。私は問題を理解しています。簡単に言うと、ストリーミングとバッファリングの両方を同じエンドポイント操作コントラクトに含めることはできません。もちろん、同じ Web サービスから複数の個別のエンドポイントを実行できます。たとえば、バッファリングを使用するものとストリーミングを使用するものなど、それぞれが異なるポートを使用します。

また、クライアント (同じエンドポイントを使用) がホストへのアップロード要求をバッファリングできる間 (またはその逆) に、ホストがその応答をストリーミングするように設定することができます。それは問題ではありません。ただし、同じホスト エンドポイントからの応答をバッファリングおよびストリーミングすることはできません。

SQL からクライアントへのダウンロードのバッファリングで同じ問題が発生しました。しばらくの間、主にクライアント デバイスのタイムアウトを解決するためにダウンロードのストリーミングを行っていましたが、ストリーミングもメモリを大量に消費することがわかりました。技術としてのストリーミングも扱いが難しいことがわかりました。そのため、ストリーミングから離れてバッファリングに戻りましたが、100 MB を超えるダウンロードにはインタラクティブな「チャンキング」アプローチを使用しています。たとえば、1 GB のパッケージを配信する必要がある場合、ホストはクライアント ソフトウェアが 1 つのファイルとして組み立てる 100 MB のチャンクでファイルを送信します。

これがお役に立てば幸いです。

于 2013-08-13T11:42:26.353 に答える