如果我正確理解你的問題,你有一個長期磨合的計算功能,例如這樣的:
static String compute()
{
int t = 300 + new Random().Next(1000);
Console.Write("[{0}...", t);
Thread.Sleep(t);
Console.Write("]");
return Guid.NewGuid().ToString();
}
你想每秒,但沒有重疊的電話至少一次調用這個函數,兩次呼叫之間的恢復時間至少爲200ms。下面的代碼適用於這種情況。
我從一個更實用的方法開始(使用Scan()
和Timestamp()
),更多的是Rx風格 - 因爲我在尋找一個很好的Rx練習 - 但最終,這種非聚合方法更簡單。
static void Main()
{
TimeSpan period = TimeSpan.FromMilliseconds(1000);
TimeSpan recovery = TimeSpan.FromMilliseconds(200);
Observable
.Repeat(Unit.Default)
.Select(_ =>
{
var s = DateTimeOffset.Now;
var x = compute();
var delay = period - (DateTimeOffset.Now - s);
if (delay < recovery)
delay = recovery;
Console.Write("+{0} ", (int)delay.TotalMilliseconds);
return Observable.Return(x).Delay(delay).First();
})
.Subscribe(Console.WriteLine);
}
這裏的輸出:
[1144...]+200 a7cb5d3d-34b9-4d44-95c9-3e363f518e52
[1183...]+200 359ad966-3be7-4027-8b95-1051e3fb20c2
[831...]+200 f433b4dc-d075-49fe-9c84-b790274982d9
[766...]+219 310c9521-7bee-4acc-bbca-81c706a4632a
[505...]+485 0715abfc-db9b-42e2-9ec7-880d7ff58126
[1244...]+200 30a3002a-924a-4a64-9669-095152906d85
[1284...]+200 e5b1cd79-da73-477c-bca0-0870f4b5c640
[354...]+641 a43c9df5-53e8-4b58-a0df-7561cf4b0483
[1094...]+200 8f25019c-77a0-4507-b05e-c9ab8b34bcc3
[993...]+200 840281bd-c8fd-4627-9324-372636f8dea3
[編輯:此示例使用的Rx 2.0(RC)2.0.20612。0]
你在倒數第二行有一個錯字。它應該是暫停而不是時間。但我真的很喜歡你的解決方案,它很簡單,然後我在下面發佈 – LDomagala