c# - .net core - 传递未知数量的 IProgress到类库
问题描述
我有一个控制台应用程序,它使用类库来执行一些长时间运行的任务。这是一个 .net core 控制台应用程序,使用 .net core Generic Host。我还使用ShellProgressBar库来显示一些进度条。
我的托管服务看起来像这样
internal class MyHostedService : IHostedService, IDisposable
{
private readonly ILogger _logger;
private readonly IMyService _myService;
private readonly IProgress<MyCustomProgress> _progress;
private readonly IApplicationLifetime _appLifetime;
private readonly ProgressBar _progressBar;
private readonly IProgressBarFactory _progressBarFactory;
public MyHostedService(
ILogger<MyHostedService> logger,
IMyService myService,
IProgressBarFactory progressBarFactory,
IApplicationLifetime appLifetime)
{
_logger = logger;
_myService = myService;
_appLifetime = appLifetime;
_progressBarFactory = progressBarFactory;
_progressBar = _progressBarFactory.GetProgressBar(); // this just returns an instance of ShellProgressBar
_progress = new Progress<MyCustomProgress>(progress =>
{
_progressBar.Tick(progress.Current);
});
}
public void Dispose()
{
_progressBar.Dispose();
}
public Task StartAsync(CancellationToken cancellationToken)
{
_myService.RunJobs(_progress);
_appLifetime.StopApplication();
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
哪里MyCustomProgress
看起来像这样
public class MyCustomProgress
{
public int Current {get; set;}
public int Total {get; set;}
}
MyService
看起来像这样( , Job1
, implement Job2
)Job3
IJob
public class MyService : IMyService
{
private void List<IJob> _jobsToRun;
public MyService()
{
_jobsToRun.Add(new Job1());
_jobsToRun.Add(new Job2());
_jobsToRun.Add(new Job3());
}
public void RunJobs(IProgress<MyCustomProgress> progress)
{
_jobsToRun.ForEach(job =>
{
job.Execute();
progress.Report(new MyCustomProgress { Current = _jobsToRun.IndexOf(job) + 1, Total = _jobsToRun.Count() });
});
}
}
并且IJob
是
public interface IJob
{
void Execute();
}
此设置运行良好,我可以HostedService
通过创建一个ShellProgressBar
实例并使用IProgress
我必须更新它的一个实例来显示我的进度条。
但是,我还有另一个实现IMyService
,我也需要运行它,看起来像这样
public class MyService2 : IMyService
{
private void List<IJob> _sequentialJobsToRun;
private void List<IJob> _parallelJobsToRun;
public MyService()
{
_sequentialJobsToRun.Add(new Job1());
_sequentialJobsToRun.Add(new Job2());
_sequentialJobsToRun.Add(new Job3());
_parallelJobsToRun.Add(new Job4());
_parallelJobsToRun.Add(new Job5());
_parallelJobsToRun.Add(new Job6());
}
public void RunJobs(IProgress<MyCustomProgress> progress)
{
_sequentialJobsToRun.ForEach(job =>
{
job.Execute();
progress.Report(new MyCustomProgress { Current = _jobsToRun.IndexOf(job) + 1, Total = _jobsToRun.Count() });
});
Parallel.ForEach(_parallelJobsToRun, job =>
{
job.Execute();
// Report progress here
});
}
}
这是我正在努力解决的问题。当_parallelJobsToRun
执行时,我需要能够创建一个新的子ShellProgressBar
( ShellProgressBar.Spawn
) 并将它们显示为让我们说“并行作业”的子进度条。
这就是我正在寻找一些关于如何实现这一目标的帮助的地方。
注意:我不想ShellProgressBar
在我的类库中依赖MyService
非常感谢任何帮助。
解决方案
根据我对您的问题的理解,问题是您如何显示同步作业和并行作业的完成进度。
理论上,并行作业可以同时开始和结束,因此您可以将并行作业视为单个作业。不要使用连续作业的计数作为总数,而是将该数字增加一。这对于少量并行作业可能是令人满意的。
如果要在并行作业之间添加进度,则需要在代码中处理多线程,因为并行作业将同时运行。
object pJobLock = new object();
int numProcessed = 0;
foreach(var parallelJob in parallelJobs)
{
parallelJob.DoWork();
lock (pJobLock)
{
numProcessed++;
progress.Report(new MyCustomProgress { Current = numProcessed, Total = parallelJobs.Count() });
}
}
推荐阅读
- ios - 警报控制器描述消息不是多行的,它会截断尾部。?
- php - 在服务器中为 cakephp3 日期时间获取不同的日期格式
- prediction - uci 心脏数据集 cleaveland 预测列有超过 2 个值(0 和 1)。这是什么意思?
- java - Java Hive 连接 executeUpdate() 始终返回计数为零
- python - 如何在 MacOs 中将 xlsx(包含数据和图像)转换为 PDF?
- wordpress - 在 Woocommerce 商店页面中显示完整的产品标题
- java - 我的 content_main.xml 的 designView 没有显示
- c# - 如何在非静态方法中使用响应?
- android - 导航完成后如何返回应用程序
- rethinkdb - 清除特定数据库的所有表