私はこの単純なコードを持っています、それは:
コードは次のとおりです。
private void DisplayPoints()
{
var x = 0;
var ob = this.GeneratePoints();
ob
.Sample(TimeSpan.FromMilliseconds(500))
.SubscribeOn(ThreadPoolScheduler.Instance)
.ObserveOn(SynchronizationContext.Current)
.Subscribe(d => Console.WriteLine(d));
}
private IObservable<double> GeneratePoints()
{
return Observable.Create<double>(o => this.GeneratePoints(o));
}
private IDisposable GeneratePoints(IObserver<double> observer)
{
var i = 0;
while (true)
{
var value = random.Next(0, 100) * (1 / (double)random.Next(1, Math.Min(50, Math.Max(i, 1))));
observer.OnNext(value);
i++;
}
return Disposable.Empty;
}
ただし、コンソールには何も出力されません(つまり、匿名のオブザーバーが呼び出されることはありません)。Sample
オペレーターを削除すると、オブザーバーが呼び出されますが、その動作は明らかに意図されていません(UIスレッドが攻撃されます)。
私は明らかにここで何かが欠けています。私の意図は、データを生成し、IObserverを介してプッシュし、UIを介してその一部を表示することです。
編集:何人かの人々が私の意図を誤解しているので(彼らは上で明確に述べられていますが)、私がやろうとしていることを繰り返します:
double
私の問題には値で十分だと思われます)IObservable
Reactive Extensionsの使用は、私の問題に対する良い解決策のように思えました。
ただ、繰り返しに:私は乱数を返しません-これはちょうどだった実際のコードにプレースホルダー私の意図した動作の作業を取得します。
タイトなループで乱数を生成したくない場合があります。時間間隔を使用することをお勧めします。以下は、200ミリ秒ごとに乱数を生成します。
IObservable<double> observable =
Observable.Interval(TimeSpan.FromMillSeconds(200))
.Select((t,i) => random.Next(0, 100)
* (1 / (double)random.Next(1, Math.Min(50, Math.Max(i, 1)))))
Enigmativityが作成したコードも、事実上タイトループです。サブスクライブプロセスで値をプッシュする際のエラーについて彼が指摘した点も正しいです。コードを機能させるために必要な最小限の変更は次のとおりです。
private static Task GeneratePoints(IObserver<double> observer, CancellationToken token)
{
return Task.Run(() =>
{
var i = 0;
var random = new Random();
while ( true )
{
token.ThrowIfCancellationRequested();
var value = random.Next(0, 100) * ( 1 / ( double ) random.Next(1, Math.Min(50, Math.Max(i, 1))) );
observer.OnNext(value);
i++;
}
});
}
今度いつか
Observable.Create<double>((observer, token) => GeneratePoints(observer, token));
キャンセルトークンが渡されていることに注意してください。シーケンスのサブスクライバーがサブスクライブを解除すると、このトークンが設定され、ループが終了します。
ただし、これは多くの作業であり、Enigmativitiesの回答はより単純であり、上記のコードを抽象化します。より複雑なケースでは、これを手動で行う方法を知っておくと便利です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加