gpt4 book ai didi

c# - 报告/监控长流程进度的设计模式

转载 作者:太空狗 更新时间:2023-10-29 19:48:07 25 4
gpt4 key购买 nike

任何人都可以建议一个好的设计模式来报告/监控长流程的状态/进度。基本上,我有一个接收“数据上下文”对象的代码库:

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

// Additional properties removed for simplicity...
}

根据提供的上下文,创建一个具有各种子任务的任务(不是 TPL-Task)对象。在执行期间,DataContext 对象被传递给各种子任务,这些子任务可以检索或更新它。

例如,假设主要任务是“复制文件”任务。 DataContext 将具有 SourceFolder 和 TargetFolder 等属性,可能还有 FilterFiles 属性(例如 *.docx)。我们的主要任务将是一个 CopyFilesTasks,它将有一个子任务的“管道”——扫描文件夹、扫描文件、过滤文件、复制文件等....

我正在寻找的是允许任务/子任务向调用者/执行者报告其进度的最佳方式。在我们上面的示例中,正在进行的更改可能只是“复制的文件 ABC.docx...”,或者可能更“复杂”一些,例如“正在扫描文件夹 XYZ...”

我考虑了以下选项:

  1. INotifyPropertyChanged:向 DataContext 添加“Progress”属性

    公共(public)字符串进度{ get;设置 { _progress = 值; RaisePropertyChanged("进度");

    并让创建 DataContext 对象的代码注册到 PropertyChanged 事件。然而,这似乎是一种过于简单化的方法......

  2. ILog(使用您喜欢的任何日志记录框架):在各种任务/子任务中使用 ILog 实例,并让主任务执行者将其自己的监听器添加到日志记录中框架。然而,这似乎扭曲了日志记录机制来做它不应该做的事情。

  3. 乌迪达汉的 DomainEvents :任务的执行者可以将DataContext视为一个“域”,因此我们可以尝试为一个“ProgressChanged”事件实现一个“EventHandler”。从理论上讲,这甚至可以用于更精细的事件,发生在特定的子任务中……但再一次,感觉像是在强加这个概念……

我的担忧包括:

  • 进度可能不是唯一需要监控的“事件”——在我们上面的例子中,我们可能希望事情更明确,比如 FolderHandled、FileCopied 等,但我们可能不知道执行任务时的确切事件(请记住 - 子任务是基于 DataContext 创建的,并且可能会导致执行不同的任务)。
  • 运行任务的上下文尚未定义。目前,我只是计划从命令行应用程序运行任务,因此需要输出到命令行以进行调试。稍后,当我将其移至服务时,我可能希望“监听器”使用任务进度更新数据库(例如)。

最佳答案

您可以为每种可能的操作类型声明参数,比如文件操作的 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);
}
}

OperationProgress 将在创建 DataContext 时指定。

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"));
}
}

关于c# - 报告/监控长流程进度的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6413448/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com