C#で進行状況バーを操作するための正しいアーキテクチャについて知りたいです。しかし、これはC#だけに適用されるのではないかもしれません。これについては、アーキテクチャを調べる必要があるためです。
質問を例を挙げて説明します。ユーザーがボタンを押すと、プログラムは巨大なアルゴリズムで動作し始めます。アルゴリズムの一部に非常に時間がかかっています。この部分は非常に低いレベルにあり、UIプロジェクトやUIクラスからはかけ離れています。ユーザーに進行状況バーを表示して、このアルゴリズムの進行状況を確認できるようにしたいと思います。
より良い方法は何ですか?アルゴリズムがある下位レベルのプロジェクトからのプログレスバーのビューを接続(参照)しても問題ありませんか?または、既存のUIプロジェクトに進行状況バーのビューを作成し、アルゴリズムの状態に関する情報を(アルゴリズムからUIまで)すべてのレベルで送信する方が良いでしょうか?または、他にもっと良い方法はありますか?
2番目の方法の方が良いと思いますが、実装は難しくなります。
長期実行アルゴリズムは確かに、その進行状況を示す何らかの方法を使用できます。ただし、アルゴリズムが進行状況バーと通信していることをアルゴリズムが認識するのは不適切です。
アルゴリズムは、進行状況についてアルゴリズムが言うことを取り、進行状況バー、ログファイル、またはオーディオスピーカー上のノイズに変換できるアダプターと通信できる必要があります。
この方法で行われると、これらのメディアへの変更はアルゴリズムに影響を与えません。変更点はアダプターのみ。
そして、それが本当にあなたにとって重要であるならば、はい、私はソフトウェアアーキテクトと呼ばれています。私はコードモンキーという言葉を好む。
これが私がこの問題に取り組んだ方法です。重要だと思う点がいくつかあります。
したがって、私はこのようなものになってしまいます
public interface IProgress {
double Completed { get; } // From 0 to 1
}
public class MyProgress : IProgress{
private IProgress[] subprogresses;
public double Completed
=>// Sums all the subprogresses, divided by the count.
public MyProgress[] Split(int count) {
// creates new MyProgress objects, sets them as subprogresses, and returns the created objects
}
public MyCountingProgress Counting(int totalCount) {
// Creates a counting progress and sets it as the only subprogress
};
}
public class MyCountingProgress : IProgress
{
public MyCountingProgress(int totalCount)
{
TotalCount = totalCount;
}
public int Count;
public int TotalCount { get; }
public double Completed => this.Count / (double)this.TotalCount;
}
呼び出しは通常、次のようになります
var progress = new MyProgress();
Task longRunningTask = DoWork(progress);
MyProgressDialog.ShowDialog("please wait", longRunningTask, progress);
進捗ダイアログは、進捗バーを更新するタイマーを開始し、完了したらダイアログを閉じるタスクの継続を登録し(これがGUIスレッドで実行されるようにTaskScheduler.FromCurrentSynchronizationContext()を使用)、モーダルダイアログを表示します。
さらにいくつかのポイント:
最初に、バックグラウンド作業を行うためのeスレッド/タスクを含むクラスを作成します。スレッドを作成して開始するメソッドを追加します。
0と1の間の数値、または現在と合計の2つの数値など、進行状況インジケーターを持つイベント引数を使用して、イベントProgressを追加します。
スレッド実行メソッドで各反復でイベントを発生させ、進行状況を報告します。
UIコンポーネントでイベントをサブスクライブします。ハンドラーメソッドのUIスレッドにマーシャリングします(Invoke for Windows Formsを使用)。
UIスレッドで実行されるコードは、進行状況バーを更新できます。
フロントエンドで進行状況を判断する場合は、 Microsoft API を使用して進行状況を報告できます。 例 サーバー側の進捗状況では、サービス層でサーバーからクライアントへのコールバックを実装する必要があります。私はあなたのアルゴリズムがサーバー側の進行状況の表示を必要としないことを想定しています。