2011-06-20 11 views
6

ロングプロセスのステータス/進行を報告/監視するための優れたデザインパターンを提案できます。提供されるコンテキストに基づいてロングプロセスの進捗状況を報告/監視するためのデザインパターン

public class DataContext : IDataContext 
{ 
    pulbic Dictionary<string, objects> Properties { get; private set; } 

    // Additional properties removed for simplicity... 
} 

、タスク(TPL-ないタスク)オブジェクトが作成され、種々のサブタスクを有する: は基本的に、私は、「データ・コンテキスト」オブジェクトを受信するコードベースを持っています。 実行中、DataContextオブジェクトは、さまざまなサブタスクに渡され、それを取得または更新できます。

たとえば、主なタスクが「ファイルのコピー」タスクであるとします。 DataContextには、SourceFolderやTargetFolder、FilterFilesプロパティ(例:* .docx)などのプロパティがあります。私たちの主な仕事はCopyFilesTasksで、スキャンフォルダ、スキャンファイル、フィルタファイル、コピーファイルなどのサブタスクのパイプラインがあります。

私が探しているのは、タスク/サブタスクが進行状況を発呼者/実行者に報告することを可能にする。 上記の例では、進行中の変更は「コピーされたファイルABC.docx ...」、または「XY XYZのスキャン」のようなもう少し複雑なものになる可能性があります。

次のオプション:

  1. をINotifyPropertyChangedの:パブリック文字列の進捗{取得のDataContext

    に "進行" プロパティを追加します。セット{_progress =値; RaisePropertyChanged( "Progress"); }

    と、PropertyChangedイベントへのDataContextオブジェクトレジスタを作成したコードがあります。さまざまなタスク/サブタスクにアイログのインスタンスを使用して、メインタスクの死刑執行を持っています。しかし、これは

  2. アイログが(あなたが好みのロギングフレームワークを使用して)...あまりにも単純化したアプローチのように思えますそれ自身のリスナーをロギングフレームワークに追加します。 しかし、これはロギングの仕組みを曲げないようにするように思えました。

  3. のUdi漢のDomainEvents:タスクの死刑執行は、「ドメイン」としてのDataContextを考えることができ、したがって、私たちは「ProgressChanged」イベントのために「のEventHandler」を実装しようとすることができます。

    :理論的には、これはさえ

私の懸念

はのようなものを含んで...特定のサブタスクに起こる...しかし、再び、それは概念を強制のように感じ、より洗練されたイベントのために使用することができます
  • 上記の例では、FolderHandled、FileCopiedなどのように定義したほうがよい場合がありますが、実行時には正確なイベントがわからない場合がありますタスク(覚えておいてください - サブタスクはDataContextに基づいて作成され、異なるタスクが実行される可能性があります)。
  • タスクを実行するコンテキストはまだ定義されていません。今のところ、私はコマンドラインアプリケーションからタスクを実行することを計画しているので、デバッグにはコマンドラインへの出力が必要です。後で、これをサービスに移すと、「リスナー」にタスクの進捗状況(たとえば)を持つデータベースを更新させたいことがあります。

答えて

0

BackgroundWorkersを検討してください。 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx 個別のUIスレッドで独自のreportprogressイベントを持ちます。

+0

は、これは私が必要なものではありません - 私は、バックグラウンドスレッドでコードを実行している問題はありません...私は中にプログレスバーを更新するために、どれだけ多くの「完全な」解決策を探していて、いませんよUI(現時点ではUIはありませんが、おそらく決してできません) – SaguiItay

1

あなたは、可能な各操作タイプの引数を宣言することができ、ファイル操作のためのFileOperationEventArgsを言って、データベース操作のためのDatabaseUpdateEventArgsなど

public class FileOperationEventArgs : EventArgs 
{ 
    public readonly string SourceFolder; 
    public readonly string TargetFolder; 

    public FileOperationEventArgs(string sourceFolder, string targetFolder) 
    { 
     SourceFolder = sourceFolder; 
     TargetFolder = targetFolder; 
    } 
} 

public class DatabaseUpdateEventArgs : EventArgs 
{ 
    public readonly int RowsUpdated; 

    public DatabaseUpdateEventArgs(int rowsUpdated) 
    { 
     RowsUpdated = rowsUpdated; 
    } 
} 

OperationProgressクラスは、各操作の種類のイベントを宣言します。

public class OperationProgress 
{ 
    public event EventHandler<FileOperationEventArgs> FileCopied; 
    public event EventHandler<DatabaseUpdateEventArgs> DatabaseUpdated; 

    public void OnFileCopied(FileOperationEventArgs a) 
    { 
     if(FileCopied != null) 
      FileCopied(this, a); 
    } 

    public void OnDatabaseUpdated(DatabaseUpdateEventArgs a) 
    { 
     if (DatabaseUpdated != null) 
      DatabaseUpdated(this, a); 
    } 
} 

DataContextの作成時にOperationProgressが指定されます。

public class DataContext : IDataContext 
{ 
    public Dictionary<string, object> Properties { get; private set; } 
    public OperationProgress Progress { get; private set; } 

    public DataContext(OperationProgress progress) 
    { 
     Progress = progress; 
    } 
} 

サブタスクの実装では、進捗状況を更新することができます。

public class FileCopySubTask 
{ 
    public void Execute(DataContext context) 
    { 
     context.Progress.OnFileCopied(new FileOperationEventArgs("c:/temp1", "c:/temp2")); 
    } 
} 
+0

これはUdi DahanのDomainEventsに似ていますが、より制限されています - 特定の「既知の」イベントのイベントのみを制限します新しいイベントの新しいタスクの場合はすべてをコンパイルする必要があります...複数のタスクと複数の "リスナー"がある場合は、イベント登録/登録解除と参照を管理する必要があります。 – SaguiItay

関連する問題