我有一个问题,我不知道如何解决。 我有一些类(处理器)使用进度信息触发事件(它的距离百分比)。有多个处理器执行此操作,并且调用它们的顶级处理器(引擎)都需要向最终用户发送有关其进度的信息。 如果我事先不知道每个处理器将处理多少项目,我怎样才能给用户一些关于这个过程有多远的好反馈?
看看下面的简化示例
class Program {
static void Main(string[] args) {
var p = new Program();
p.Run();
}
private void Run() {
var engine = new Engine();
engine.UpdateProgress += Engine_UpdateProgress;
engine.Process();
Console.ReadLine();
}
private void Engine_UpdateProgress(object sender, UpdateProgressEventArgs e) {
Console.WriteLine($"{e.UpdateDateTime} - Caller: {e.Caller}, Percentage: {e.Percentage}");
}
}
public class Engine {
private readonly ProcessorA _processorA;
private readonly ProcessorB _processorB;
private readonly ProcessorC _processorC;
private readonly ProcessorD _processorD;
public event EventHandler<UpdateProgressEventArgs> UpdateProgress;
public Engine() {
_processorA = new ProcessorA();
_processorB = new ProcessorB();
_processorC = new ProcessorC();
_processorD = new ProcessorD();
//Handle events
_processorA.UpdateProgress += ProcessorA_UpdateProgress;
_processorB.UpdateProgress += ProcessorA_UpdateProgress;
_processorC.UpdateProgress += ProcessorA_UpdateProgress;
_processorD.UpdateProgress += ProcessorA_UpdateProgress;
}
private void ProcessorA_UpdateProgress(object sender, UpdateProgressEventArgs e) {
OnUpdateProgress(e);
}
public void Process() {
_processorA.Process();
_processorB.Process();
_processorC.Process();
_processorD.Process();
}
protected virtual void OnUpdateProgress(UpdateProgressEventArgs e) {
UpdateProgress?.Invoke(this, e);
}
}
public class ProcessorA : Processor {
private readonly ProcessorA_A _processorA_A;
public ProcessorA() {
_processorA_A = new ProcessorA_A();
//Handle events
_processorA_A.UpdateProgress += ProcessorA_A_UpdateProgress;
}
public void Process() {
_processorA_A.Process();
}
private void ProcessorA_A_UpdateProgress(object sender, UpdateProgressEventArgs e) {
OnUpdateProgress(e);
}
}
public class ProcessorB : Processor {
public void Process() {
for (int i = 0; i <= 100; i++) {
var args = new UpdateProgressEventArgs() { Caller = nameof(ProcessorB), Percentage = i, UpdateDateTime = DateTime.Now};
//Do some work
Thread.Sleep(r.Next(50,250));
OnUpdateProgress(args);
}
}
}
public class ProcessorC : Processor {
public void Process() {
for (int i = 0; i <= 100; i++) {
var args = new UpdateProgressEventArgs() { Caller = nameof(ProcessorC), Percentage = i, UpdateDateTime = DateTime.Now };
//Do some work
Thread.Sleep(r.Next(50, 250));
OnUpdateProgress(args);
}
}
}
public class ProcessorD : Processor {
public void Process() {
for (int i = 0; i <= 100; i++) {
var args = new UpdateProgressEventArgs() { Caller = nameof(ProcessorD), Percentage = i, UpdateDateTime = DateTime.Now };
//Do some work
Thread.Sleep(r.Next(50, 250));
OnUpdateProgress(args);
}
}
}
public class ProcessorA_A : Processor {
public void Process() {
for (int i = 0; i <= 100; i++) {
var args = new UpdateProgressEventArgs() { Caller = nameof(ProcessorA_A), Percentage = i, UpdateDateTime = DateTime.Now };
//Do some work
Thread.Sleep(r.Next(50, 250));
OnUpdateProgress(args);
}
}
}
public class Processor : IProcessor {
protected Random r = new Random();
public event EventHandler<UpdateProgressEventArgs> UpdateProgress;
protected virtual void OnUpdateProgress(UpdateProgressEventArgs e) {
UpdateProgress?.Invoke(this, e);
}
}
public interface IProcessor {
event EventHandler<UpdateProgressEventArgs> UpdateProgress;
}
public class UpdateProgressEventArgs {
public int Percentage { get; set; }
public string Caller { get; set; }
public DateTime UpdateDateTime { get; set; }
}
只是将进度从孩子发送到父母就不会明显地做到这一点。我希望有人可以帮我找到解决方案。或者,如果有人有另一个出色的解决方案:)
提前致谢
答案 0 :(得分:3)
引擎可以维护一个私人列表&#34;最后的完整性&#34;每个过程。在字典中很可能。
如果我们扩展你的Engine
课程,那就是这个。
private Dictionary<IProcessor, int> _lastReportedPercentage = new Dictionary<IProcessor, int>();
并在定义了所有子处理器的构造函数中,将它们全部设置为0。
public Engine()
{
//your other stuff
_lastReportedPercentage[_processorA] = 0;
_lastReportedPercentage[_processorB] = 0;
_lastReportedPercentage[_processorC] = 0;
_lastReportedPercentage[_processorD] = 0;
}
子进程的事件处理程序中的执行以下操作:
private void ProcessorA_UpdateProgress(object sender, UpdateProgressEventArgs e)
{
_lastReportedPercentage[(IProcessor)sender] = e.Percentage;
var totalCompleteness = (int)Math.Floor(_lastReportedPercentage.Values.Sum() / _lastReportedPercentages.Values.Count);
OnUpdateProgress(new UpdateProgressEventArgs() { Caller = nameof(Engine), Percentage = totalCompleteness, UpdateDateTime = DateTime.Now });
}
然后,您将从引擎中报告所有任务的完整性。
这有一些明显的设计缺陷,但你明白了。如果它们从非构造函数等加载,它可以扩展为可变数量的处理器,但这应该为您提供您想要的所需输出。
答案 1 :(得分:0)
我建议让每个处理器计算完成的项目数量,以及剩余的项目数量。
这样,只要项目完成,以及将项目添加到处理器,引擎就会收到更新。
在Skintkingle的回答中,您将存储引擎内每个处理器的最后一次接收更新。
然后,您可以让引擎决定放置此信息的最佳方式。像完成总数/剩余总数这样简单的东西会运作良好。