Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 每100ms获取一次可观测值,但始终获取最终值_C#_System.reactive - Fatal编程技术网

C# 每100ms获取一次可观测值,但始终获取最终值

C# 每100ms获取一次可观测值,但始终获取最终值,c#,system.reactive,C#,System.reactive,我有一个worker,它公开一个主题,它可以非常快速地发布日志消息。写入控制台的速度很慢,所以我最多只想每100ms写入一次控制台。任务完成后,我想写出最新发布的字符串,以避免像完成工作2312/2400…完成这样的事情。(或者甚至是…done如果任务需要这就是我想出的代码,它似乎可以完成任务。不过我不确定它有多正确或惯用 var observable = Worker.GetObservable(); //Actually a Subject<string> Action<s

我有一个worker,它公开一个
主题
,它可以非常快速地发布日志消息。写入控制台的速度很慢,所以我最多只想每100ms写入一次控制台。任务完成后,我想写出最新发布的字符串,以避免像
完成工作2312/2400…完成这样的事情。(或者甚至是
…done
如果任务需要这就是我想出的代码,它似乎可以完成任务。不过我不确定它有多正确或惯用

var observable = Worker.GetObservable(); //Actually a Subject<string>
Action<string> log = x => Console.Write("\r" + x);
string latest = "";
using(observable.Subscribe(x => latest = x))
using(observable.Sample(TimeSpan.FromMilliseconds(100)).Subscribe(log))
{
    Worker.DoWorkWithLogs();
    log(latest);
}
Console.WriteLine(" ...done.");
var observable=Worker.GetObservable();//实际上是一个主题
操作日志=x=>Console.Write(“\r”+x);
字符串latest=“”;
使用(observable.Subscribe(x=>latest=x))
使用(observable.Sample(TimeSpan.frommilluses(100)).Subscribe(log))
{
Worker.DoWorkWithLogs();
日志(最新版本);
}
控制台。WriteLine(“…完成”);

这是我提出的代码,它似乎可以完成这项工作。但我不确定它是否正确或惯用

var observable = Worker.GetObservable(); //Actually a Subject<string>
Action<string> log = x => Console.Write("\r" + x);
string latest = "";
using(observable.Subscribe(x => latest = x))
using(observable.Sample(TimeSpan.FromMilliseconds(100)).Subscribe(log))
{
    Worker.DoWorkWithLogs();
    log(latest);
}
Console.WriteLine(" ...done.");
var observable=Worker.GetObservable();//实际上是一个主题
操作日志=x=>Console.Write(“\r”+x);
字符串latest=“”;
使用(observable.Subscribe(x=>latest=x))
使用(observable.Sample(TimeSpan.frommilluses(100)).Subscribe(log))
{
Worker.DoWorkWithLogs();
日志(最新版本);
}
控制台。WriteLine(“…完成”);

事实上,如果事件源的可观察对象在完成时被称为
OnCompleted()
,那么它比你想象的要简单。这本身就可以做到:

observable.Sample(TimeSpan.FromMilliseconds(100)).Subscribe(log);
这是因为
Sample
将在其事件源完成时触发最后一次。以下是完整测试:

var sub = new Subject<string>();
var gen = Observable.Interval(TimeSpan.FromMilliseconds(50)).Select((_,i) => i).Subscribe(i => sub.OnNext(i.ToString()));

sub.Sample(TimeSpan.FromSeconds(1))
   .Subscribe(Console.WriteLine);

Thread.Sleep(3500);
sub.OnCompleted();
var sub=新主题();
var gen=Observable.Interval(TimeSpan.frommilluses(50)).Select((uu,i)=>i.Subscribe(i=>sub.OnNext(i.ToString());
子示例(从秒开始的时间跨度(1))
.Subscribe(Console.WriteLine);
睡眠(3500);
sub.OnCompleted();
即使我睡眠3.5秒,也会触发4个事件,最后一个事件在我调用
OnCompleted()
时触发


另一点需要注意的是,如果
Worker.GetObservable()是错误的形式
实际上返回一个
主题
——即使是在工人类中,它真正应该做的是只返回
IObservable
接口。这不仅仅是一种风格,它是一种关注点的分离,返回所需的最小功能接口。

它实际上比你想象的要简单如果事件源的可观察对象在完成时称为
OnCompleted()
。这将自行完成:

observable.Sample(TimeSpan.FromMilliseconds(100)).Subscribe(log);
这是因为
Sample
将在其事件源完成时触发最后一次。以下是完整测试:

var sub = new Subject<string>();
var gen = Observable.Interval(TimeSpan.FromMilliseconds(50)).Select((_,i) => i).Subscribe(i => sub.OnNext(i.ToString()));

sub.Sample(TimeSpan.FromSeconds(1))
   .Subscribe(Console.WriteLine);

Thread.Sleep(3500);
sub.OnCompleted();
var sub=新主题();
var gen=Observable.Interval(TimeSpan.frommilluses(50)).Select((uu,i)=>i.Subscribe(i=>sub.OnNext(i.ToString());
子示例(从秒开始的时间跨度(1))
.Subscribe(Console.WriteLine);
睡眠(3500);
sub.OnCompleted();
即使我睡眠3.5秒,也会触发4个事件,最后一个事件在我调用
OnCompleted()
时触发


另一点需要注意的是,如果
Worker.GetObservable()是错误的形式
实际上返回一个
主题
——即使它是工人类的主题,它真正应该做的是只返回
IObservable
接口。这不仅仅是一种风格,它是一种关注点分离,返回所需的最低功能接口。

您可以使用函数。

您可以使用函数。

您的主题是否调用了“OnCompleted”?您的主题是否调用了“OnCompleted”?请注意,您可以使用AsObservable来隐藏底层对象的标识,在本例中为主题。如果您只是将对象作为IObservable返回,用户仍然可以将数据回传给IObserver并输入。AsObservable正是在这里,您正在寻找帮助您实现“关注点分离”。@BartDeSmet非常优秀,不知道仅仅返回
IObservable
是不够的。这是黄金。如果我尝试在未完成的调用后执行Console.WriteLine(“完成”),那么“完成”出现在由OnCompleted调用产生的写入之前…但这可能是一个单独的问题…啊,找到了Subscribe重载,它在完成时执行操作。我将在其中写出完成的操作。请注意,您可以使用AsObservable隐藏基础对象的标识,在本例中是主题。如果您只是将对象作为IOB返回可观测的,用户仍然可以回溯到IObserver并输入数据。AsObservable正是您在这里寻找的帮助您“分离关注点”的工具。@BartDeSmet非常好,不知道仅仅返回
IObservable
是不够的。这是黄金。如果我尝试使用Console.WriteLine(“完成”)在OnCompleted调用之后,在OnCompleted调用产生的写入之前出现“Done.”但这可能是一个单独的问题……啊,找到了Subscribe重载,它在OnCompleted中执行操作。我将在其中写出Done。