2017-02-25 35 views
1

Taskを作成し、バッチでデータを読み取るクラスReaderがあります。バッチの読み込みが完了するたびに、IProgressによって進捗がパラメータとして渡されます。次に、バッチをNoSQLデータベースに保存します。問題は、バッチをデータベースに保存するよりも速く進行状況を報告できることです。ブロック非同期タスク

保存がまだ完了していない場合は、Taskをブロックするのがよい解決策だと思います。私はそれをどのように実装するのか本当に分かりません。私は読書が終わったことを知らせる何かが必要で、dbへの保存が終了して読書を続けるという通知を待つ。

擬似コード:

リーダー:

public async Task<bool> ReadAsync(IProgress<Tuple<DataTable, int>> statusCallback) { 
    return await Task.Run(() => 
    { 
     while(lineCount <= BufferSize) { 
     // Read data 
     } 
    statusCallback.Report(new Tuple<DataTable, int>(data, progress); 
    } 
} 

メイン:

public Main() { 
    var progress = new Progress<Tuple<DataTable, int>>(ReaderStatusCallback); 
    reader.ReadAsync(progress); 
} 

private void ReaderStatusCallback(Tuple<DataTable, int> tuple) 
{ 
    var data = tuple.Item1.ToDocumentData(); 
    var progress = tuple.Item2; 

    _progressBar.Increment(progress); 
    _docData.Data = data; 
    _repository.Add(_docData); 
} 
+0

保存タスクも非同期ですか? – Sparrow

+0

いいえ、UIスレッド – FCin

+0

に保存します。擬似コードを投稿していればアイデアを出しやすくなります。私は読者クラスがループを使用していると仮定しています。おそらく、保存のためのシングルトンクラスを持つことができ、それがビジーであるかどうかを示すフラグを持っていて、リーダーループで新しいバッチを読み込む前にそのフラグをチェックしてください。あなたは気が散ってイベントを使って、保存が終わったときに読者のクラスに知らせることができます。あるいはループを使用して、準備ができるまでフラグの値を絶えずチェックすることができます。非同期メソッドを待っている(またはブロックしている)のは、非同期プログラミングのアイデアとは多少異なりますが、 – Sparrow

答えて

0

ここで最も簡単な解決策は、非同期更新を派遣IProgress<T>の実装を使用しないことです。例:

class BasicProgress<T> : IProgress<T> 
{ 
    private readonly Action<T> _handler; 

    public BasicProgress(Action<T> handler) 
    { 
     _handler = handler; 
    } 

    private void IProgress<T>.Report(T value) 
    { 
     _handler(value); 
    } 
} 

statusCallback.Report()の呼び出しは、データベースが更新されるまで戻りません。

これ以上の文脈がなければ、実際に何が最良かはっきりと言うことはできません。しかし、データベース更新が少なくともある程度はキューに入れられるようにするには、ある程度の価値があるかもしれません。その場合は、同期IProgress<T>の実装をそのまま使用して、ReaderStatusCallback()メソッドで更新を非同期的にディスパッチし、それらのどれが現在未処理であるかを把握するためのカウンタを追加し、コールバックで待機するそのカウンタはある妥当なしきい値を超えています。

今、すべてのことがわかりました;あなたはこの問題に遭遇している可能性が高いと思われます。そのような場合は、なぜこれを非同期的に行うべきなのか疑問です。おそらく、非同期的なアプローチを正当化する共有していないものがあるかもしれませんが、これまでに投稿した内容に基づいて、読み込みと更新のデータベースロジック全体が単一のスレッド/ワーカー/タスク/なんでも。