【发布时间】:2012-08-30 17:51:51
【问题描述】:
我想写一个类来触发一个事件x 每秒预定义的次数调用它n。
但是,我希望x 不在每一秒内均匀地发射。
所以,假设n = 100,前 300 毫秒可能会触发 25 个,然后在接下来的 600 毫秒内再触发 50 个,在剩余的 100 毫秒内触发最后 25 个。
理想情况下,我希望粒度比上面介绍的更好,每秒内的间距范围更大。
我想知道我是否能够创建一个具有定义毫秒数的数组以及要触发多少个事件。然后使用循环和Stopwatch 类来确定是否应该触发为该毫秒航点定义的事件。
问题是,每秒计算数组的速度是否足够快,每一秒都应该有随机间距。
显然,事件需要是异步的,以避免被连接到它的东西延迟。
有人遇到过类似的需求吗?
更新
我想我至少会把我最初的努力放在这里。
所以我发现有足够的分辨率来检查你当前处于哪一毫秒以及哪一秒。基本上,我每毫秒重建间隔的每一秒都会在数组中获得一个条目,每个条目表示该毫秒触发事件的次数。
我的问题是间距...我需要一种更好的方法来尝试聚集事件计数,目前这个 jsut 似乎将它们以 0、1 或 2 的间距均匀分布。
public delegate void EmptyEventDelegate();
public class RandEvent
{
public event EmptyEventDelegate OnEvent = delegate { };
private bool running = false;
Random r = new Random();
private int eventsPS;
public RandEvent(int eventsPS = 1)
{
this.eventsPS = eventsPS;
}
public void Start()
{
running = true;
Task.Factory.StartNew(() =>
{
Run();
});
}
private void Run()
{
var sw = new Stopwatch();
sw.Start();
int currentSecond = 0;
int[] eventCount = BuildEventSpacing();
while(running)
{
if (currentSecond != sw.Elapsed.Seconds)
{
currentSecond = sw.Elapsed.Seconds;
eventCount = BuildEventSpacing();
}
else
{
for(int i = 0; i < eventCount[sw.Elapsed.Milliseconds]; i++)
OnEvent();
}
}
sw.Stop();
}
private int[] BuildEventSpacing()
{
var array = new int[1000];
for (int i = 0; i < eventsPS; i++)
{
array[r.Next(0, 999)]++;
}
return array;
}
public void Stop()
{
running = false;
}
}
【问题讨论】:
-
我记得这里有一个类似的问题:stackoverflow.com/questions/10178299/…。基本思想是将所有事件间隔为(1000ms / x)的“平均值”,但是您将它们随机移动到远离平均值的距离。它们的间距有些均匀,但仍然相对随机。链接的问题会生成一个总和为总和的随机列表,因此如果您生成一个总和为 1 的列表,您可以将每个条目解释为在事件之间等待的
ms的数量。 -
您将很难让任何 .NET 计时器每秒触发 100 次。见informit.com/guides/content.aspx?g=dotnet&seqNum=815。如果您想要更好的分辨率,则必须包装系统计时器对象之一。一个例子请参见informit.com/guides/content.aspx?g=dotnet&seqNum=817。
-
+1 @JimMischel Windows 不是 RT 有很多原因导致即使毫秒分辨率较低,事件也将是不确定的。
标签: c#