在C#中使用反应性扩展时如何显示进度 [英] How to do I show progress when using Reactive Extensions in C#
问题描述
Am在C#中使用反应性扩展来执行一些计算.到目前为止,这是我的代码的样子.我尝试将代码包装起来,以便在Calculate方法中执行一系列任务时可以显示进度
Am using reactive extensions in C# to perform some calculations. Here is how my code looks like so far. I have tried to wrap the code around so that I can show progress while to executing a series of tasks within my Calculate method
这是可观察的
IObservable<ResultWithProgress<SampleResult>> Calculate(){
return Observable.Create<ResultWithProgress<SampleResult>>(obs => {
var someTask = DoSomeTask1();
obs.OnNext(new ResultWithProgress(){Progress = 25, ProgressText ="Completed Task1"});
var someOtherTask = DoSomeMoreTask();
obs.OnNext(new ResultWithProgress(){Progress = 50, ProgressText ="Completed Task2"});
var calcResult = DoSomeMoreTask2();
obs.OnNext(new ResultWithProgress(){Progress = 75, ProgressText = "Completed Task3"});
var calcResult = FinalCalc();
obs.OnNext(new ResultWithProgress(){Progress = 100, ProgressText ="Completed Task4", Result = calcResult});
obs.OnCompleted();
}
}
结果类包装进度和结果
class ResultWithProgress<T>{
public int Progress {get; set;}
public Result T {get; set;}
public string ProgressText {get; set;}
}
包含最终结果的结果对象 类SampleResult {}
Result object which contains the final result class SampleResult{}
用法:
Calculate().Subscribe(resultWithProgress => {
if(resultWithProgress.Result == null) //Show progress using resultWithProgress.Progress
else // get the result
})
我某种程度上觉得这可能不是最好的方法.感觉很多次创建ResultWithProgress对象而没有Result的感觉似乎是一种代码味道,特别是如果我想在Calculate()内执行超过10个任务的时候
I somehow feel that this might not the best way to do it. It feels that creating ResultWithProgress object many times without the Result seems like a code smell, especially if I have more than 10 tasks that I want to do within my Calculate()
如果您能给我任何有关如何使用它的指示,或者我是否错误地解决了这个问题,我将不胜感激?
I would appreciate it if you can give me any pointers on how to use this or am I approaching this problem wrongly?
推荐答案
此答案使用了谜题答案讨论的相同原理.
This answer uses the same principles Enigmativity's answer discusses.
此版本使用Create
的异步重载.
This version uses the async overload of Create
.
它还利用.NET 4.5 IProgress 而不是原始的Action<T>
来报告进度.
It also makes use of the .NET 4.5 IProgress instead of a raw Action<T>
to report progress.
struct CalculationProgress
{
public int Progress { get; private set; }
public string ProgressText { get; private set; }
public CalculationProgress(int progress, string progressText)
: this()
{
Progress = progress;
ProgressText = progressText;
}
}
public IObservable<Result> Calculate(IProgress<CalculationProgress> progress)
{
return Observable.Create<Result>((observer, cancellationToken) =>
{
// run the work on a background thread
// so we do not block the subscriber
// and thus the subscriber has a chance
// to unsubscribe (and cancel the work if desired)
return Task.Run(() =>
{
DoSomeTask1();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(25, "First task"));
DoSomeTask2();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(50, "Second task"));
DoSomeTask3();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(75, "third task"));
var result = DoFinalCalculation();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(100, "final task"));
observer.OnNext(result);
}, cancellationToken);
});
}
这篇关于在C#中使用反应性扩展时如何显示进度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!