非同期で DataSet を分割して取得する方法

  Web Service において DataSet を利用する場合、そのデータ量によっては広帯域のネットワークを必要とする場合がある。このような場合においても、一部のデータを先に表示することでユーザーの作業が開始できる場合もある。DataSetを分割して取得することは、Web Service の帯域負荷を軽減し、初期表示までの時間を短縮することが可能になります。
 このように分割して取得するには以下の項目を考慮する必要があります。
考慮すべき項目
1.分割状態を管理するカウンタまたはステータス(初回、継続)
2.初回処理メソッド、継続処理中メソッド
   ・初回処理 : DataTable・DataViewの生成、必要なコントロールへのDataBinding (個別処理が必要 → 外部メソッド)
   ・継続処理 : 読込んだDataSteへのマージ処理 (共通化可能)
【使い方】

 DataSet 分割読込み完了時のコールバックメソッドのサンプルです。
// EndReadMethod は、DataSet読込み非同期コールバックメソッド
// InitializeMethod は、DataSet読込み後処理メソッド(初回のみ)
// this.FirstStep は、分割読込み時の初回判定フラグ

/// <summary>DataSet取得非同期コールバックメソッドハンドラ。</summary>
public delegate DataSet CallbackDataSetHandler( System.IAsyncResult ar );
/// <summary>後処理メソッドハンドラ(結果DataSet渡し)。</summary>
public delegate void    AfterCallbackDataSetHandler( System.Data.DataSet ds );

/// <summary>
///  DataSet読み取り非同期のメソッドの完了時コールバックメソッド。
/// </summary>
/// <param name="ar">非同期操作のステータス。</param>
public void Read_CallBack( System.IAsyncResult ar )
{
    //====================
    // データの読込み
    //====================
    //Debug.WriteLine("Read_CallBack Start");

    // DataSetを取得する
    DataSet dsWork;

    try
    {
        dsWork = EndReadMethod(ar);

        //Debug.WriteLine("EndReadMethod End:");
    }
    catch( Exception ex )
    {
        MessageBox.Show("データの読込みに失敗しました。", "エラー",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
        //Debug.WriteLine("EndReadMethod Error:" + ex.Message);
        return;
    }

    // 読込んだDataSetがnullか確認する
    if ( dsWork == null )
    {
        MessageBox.Show("データの読込みができませんでした。", "エラー",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    else
    {
        // 後処理メソッドへの引数設定(読込んだDataSetを設定)
        m_Args[0] = dsWork;
        
        // 初回読込みの場合、DataSetに設定する
        if ( this.FirstStep )
        {
            // 旧DataSetの開放
            if ( this.DataSource != null )
                this.DataSource.Dispose();

            this.DataSource = dsWork;

            if ( InitializeMethod == null )
                throw new ArgumentException("読込み初期処理メソッド\"InitializeMethod\"が設定されていません。");
            
            // 読み込んだデータの初期設定する(コントロールへの連結、DataTable/DataViewの生成)
            this.Parent.Invoke( InitializeMethod, m_Args );
        }
        else
        {
            // 読み込んだデータを既存データにマージに設定する
            this.Parent.Invoke( new AfterCallbackDataSetHandler( _AfterReadMethod ), m_Args );
        }
    }
}

/// <summary>
///  追加読込み時の内部処理メソッド。
///  複数のDataTableを既存のDataSetにマージする処理(分割読込み対応)
/// </summary>
private void _AfterReadMethod( System.Data.DataSet ds )
{
    //Debug.WriteLine("_AfterReadMethod Start:");
            
    // DataSetがnullの場合Exit
    if ( ds == null )
        return;

    bool flag = false;    // レコード存在チェックフラグ、初期値false

    // DataSet内の全Tableでデータレコードの存在チェック
    foreach ( DataTable dt in ds.Tables )
    {
        if ( dt.Rows.Count == 0 )
            continue;

        flag = true;
        break;
    }

    // レコードが存在する場合、マージする
    if ( flag )
    {
        // 既存レコードに追加
        this.DataSource.Merge(ds);

        if ( this.MsgControl != null )
            this.MsgControl.Text = "データを追加読込みしました。";
    }

    // WorkDataSetの開放
    ds.Dispose();
}
【注意】
戻る