11

ここ数か月、ユーザーに進行状況を報告するためのクリーンなコードを考え出すのに苦労しました。すべてが常に次のように要約されます。

ReportProgress("Starting Task 1");
doTask1();
ReportProgress("Task 1 is done");

ReportProgress("Starting Task 2");
doTask2();
ReportProgress("Task 2 is done");

//etc... where report progress does some form of output to the user.

私の中の優れたコーダーは、「もっとクリーンな方法が必要だ!」と叫びます。しかし、私は困惑しています。何かご意見は?

EDIT ::実装固有ではなく、アーキテクチャ情報に関する情報をもっと探しています。与えられたコードは非常に単純化されています。

4

13 に答える 13

9

タスクをイベント ストリームとして設定し、イベント処理「エンジン」に進行状況を報告させます。そこまで行きたい場合は、各イベント インスタンスに独自の名前、進行状況報告の宣伝文句/テンプレートなどを設定できます。

これが頻繁に発生するパターンである場合は、インフラストラクチャに努力する価値があります。完了すると、使用可能なコードは次のようになります。

EventQueue tasks = new EventQueue();
tasks.Add(new TaskEvent(this.doTask1,"Foo-ing the bar"));
tasks.Add(new TaskEvent(this.doTask2,"Bar-ing the foo"));
tasks.Add(new TaskEvent(this.doTask3,"Glitching and whinging"));
...
tasks.Execute(this.ProgressEventHandler);
于 2008-11-17T22:23:50.157 に答える
3

おそらくAspect Oriented Programmingを使用して、Progress Aspect を考案できますか?

多くの AOP 実装があります。Java の世界では、最も一般的な 2 つが AspectJ と Spring (AspectJ またはプロキシ ベースのアスペクトを使用) です。

于 2008-11-17T22:11:26.687 に答える
3

name プロパティとデリゲートを持つ Task クラスを作成できます。各タスクをコレクションに入れ、それを反復処理して、メッセージを出力し、各タスクのデリゲートを呼び出します。

于 2008-11-17T22:15:04.340 に答える
2

その場で必要な構成の量によって異なりますが、コードは非常に一般的であり、Springまたは任意のiocコンテナーを介してタスクをセットアップする必要があります。

これはすべてSpring構成に含まれます。xml構成はタスクオブジェクトにその名前とパラメーターを提供します。次に、これらのタスクをコレクションに追加し、そのコレクションをタスクランナーに渡します。

タスクランナーは、各タスクの停止と開始を通知するコードですが、各タスクは、進行中の特定のステータスを自由に指定できます。また、タスクランナーは例外をキャッチし、何かがエラーになった場合に続行します。特定のタスクが他のタスクの完了に依存し、一部のタスクが失敗した場合はすべてを停止する必要があると言うように構成可能にすることができます。

ここでAOPを使用することに同意しません。やり過ぎ。

于 2008-11-17T23:19:09.607 に答える
1

AOPの提案に+1。これは、AOP がエレガントに解決する古典的な分野横断的な問題です。

于 2008-11-17T22:41:47.420 に答える
1

do()かなり単純でクリーンな方法は、メソッドと抽象 doTask() および getName() メソッドを持つ抽象クラスを作成することです。

do() {
    ReportProgress("Starting " + this.getName());
    doTask();
    ReportProgress("Finished " + this.getName());
}

次に、タスクで:

class Task1 extends Task {
    getName(){return "Task 1";}
    doTask() {
        //do stuff here
    }
}

do()その後、他のタスク全体で実行される doTask() メソッドを持つ Task を持つことができます。これは、任意のタスクが多数のサブタスクを実行する可能性があるという点で、簡単に再帰的になる可能性があります。

于 2008-11-17T22:31:53.167 に答える
1

doTask() 呼び出し内にレポートを作成するのは自然なことです。
通常、レポーターは、すべてのオブジェクトがメッセージを送信するシングルトンであり、レポーター クラスは、ステータスバー、ログ ファイル、stderr など、表示するかどうか、および表示する場所を決定する責任を負います。

于 2008-11-17T22:11:43.660 に答える
1

あなたがやっていることのパターンは次のとおりです。

  • ログタスクの開始
  • タスクを行う
  • ログタスク終了

do() メソッドがサブクラス化され、タスクの開始と終了を自動的に記録する「タスク」クラス (すべてのタスクの親) を持つことができます。

ただのアイデア。

于 2008-11-17T22:12:10.147 に答える
1

表示されるメッセージの数値部分をそのように手作業でコード化することはしません (アクションを追加または削除したり、シーケンスを変更したりする必要があるときはいつでも、カット アンド ペーストを行う必要があります)。ReportProgress メソッドを処理しているオブジェクトは、進行に合わせて自動インクリメントする必要があります。

于 2008-11-17T22:15:23.917 に答える
0

.NETを使用している場合は、エンタープライズライブラリ(最小バージョン:3.1)のポリシーインジェクションアプリケーションブロックを使用することをお勧めします。私は同様のことを使用して、なりすましが多いWebサイトの「アプリケーションプールIDに戻す」を実行しました。

あなたはあなたの仕事で同じことをすることができます。Enterprise Libraryオブジェクトファクトリを使用してオブジェクトをビルドするファクトリを使用してタスククラスを定義し、タスクに「Before」および「After」メッセージを自動的に追加するだけです。それはあなたが必要とする優雅さであなたが望むものを正確に与えるでしょう。

楽しむ!

于 2008-11-17T23:20:53.597 に答える
0

ツール キットには、タスクを管理するタスク コントローラーがあります。タスクはスレッドとして実行されます。一般的なスレッドのサポートに加えて、タスクは進行メソッドをサポートします。進行状況を表示できるビューの 1 つは、タスク名とタスク内のステップを参照するタイトルが付いた視覚的な進行状況バーです。目に見える統計とステータスをサポートするために、コードはタスクの進捗メソッドをときどき呼び出す必要があります。通常、進行状況のパーセンテージは現在のインデックスを制限で割ることで推定できるため、これは for ループ内で実行されます。

タスク コントローラーは、グローバル スレッド制御、ステータス プローブ、その他の統計およびパフォーマンス測定フックを追加するのに便利な場所です。一部のマルチスレッドのバグとタイミングの問題は、コントローラーの状態とすべてのタスクの状態を調べることで分析できます。

于 2008-11-17T23:15:28.663 に答える
0

残念ながら、これを行う最善の方法は、詳細に依存すると思います-少なくとも、使用している言語. たとえば、Python では、コンテキスト マネージャーを使用して、次のようなコードを記述できます。

with progress_report("Task 1"):
    do_task_1()

これにより、たとえば、do_task_1() が例外を発生させた場合でも、「タスク 1 が完了しました」が報告されるようになります。必要に応じて、例外を個別に処理し、「タスク 1 が失敗しました」や「タスク 1 が中止されました」などの別の内容を出力できます。

于 2008-11-17T23:02:25.290 に答える
0

doTask メソッド内から ReportProgress を呼び出すことができます。これにより、少しきれいに見えるかもしれませんが、代わりに次のようになります。

doTask1();
doTask2();

レポートは、これらのメソッド内で処理されます。

AOP を使用することもできますが、この場合、私の脳は KISS!! (Keep It Simple Stupid) と叫びます。これが、扱っているより複雑なものの単純な表現である場合は、AOP がオプションになる可能性があります。

于 2008-11-17T22:14:24.497 に答える