2

サーバーからデータをチャンクでプルし、処理のために返すメソッドがあります。いくつかの測定を行ったところ、バックグラウンドでチャンクをダウンロードし、BlockingCollection<T>. これにより、クライアントとサーバーは互いに待機するのではなく、同時に動作できます。

public static IEnumerable<DataRecord> GetData(String serverAddress, Int64 dataID)
{
    BlockingCollection<DataRecord> records = new BlockingCollection<DataRecord>();

    Task.Run(
        () =>
        {
            Boolean isMoreData = false;
            do
            {
                // make server request and process response
                // this block can throw

                records.Add(response.record);
                isMoreData = response.IsMoreData;
            }
            while (isMoreData);

            records.CompleteAdding();
        });

    return records.GetConsumingEnumerable();
}

呼び出し元 (C++/CLI ライブラリ) は、例外が発生したことを認識して、必要に応じて再試行または救済できるようにする必要があります。戻り値の型を最小限に変更しながら、呼び出し元に例外を伝達する最良の方法は何ですか?

4

2 に答える 2

0

私が見つけた最も簡単な解決策はDataResult、レコードが列挙された後に例外が含まれている可能性があるコンテキストを返すことです。

public class DataResult
{
    internal DataResult(IEnumerable<DataRecord> records)
    {
        Records = records;
    }

    public IEnumerable<DataRecord> Records { get; private set; }
    public Exception Exception { get; internal set; }
}

public static DataResult GetData(String serverAddress, Int64 dataID)
{
    BlockingCollection<DataRecord> records = new BlockingCollection<DataRecord>();
    DataResult result = new DataResult(records.GetConsumingEnumerable());

    Task.Run(
        () =>
        {
            try
            {
                Boolean isMoreData = false;
                do
                {
                    // make server request and process response
                    // this block can throw

                    records.Add(response.record);
                    isMoreData = response.IsMoreData;
                }
                while (isMoreData);
            }
            catch (Exception ex)
            {
                result.Exception = ex;
            }
            finally
            {
                records.CompleteAdding();
            }
        });

    return result;
}

例外があった場合、呼び出し元 (C++/CLI) はそれを再スローできます。

void Caller()
{
    DataResult^ result = GetData("http://foo.com/Service", 22);

    foreach (DataRecord record in result->Records)
    {
        // process records
    }

    Exception^ ex = result->Exception;
    if (ex != nullptr)
    {
        throw ex;
    }
}
于 2014-07-09T16:30:37.543 に答える