patterncsharpMinor
qos method call using DateTime and Stopwatch
Viewed 0 times
stopwatchqosmethodcallusinganddatetime
Problem
I need to limit method call to 80 times per second (for each
My initial version:
I've decided to replace
```
private const int MAX_TRANSACTIONS_PER_PERIOD = 80;
private const int PERIOD_IN_MS = 1000;
private Queue[] times = new Queue[10]
{
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100)
};
private Stopwatch workingTime = Stopwatch.StartNew();
private int ExecTransWithStats(int connection_id, string name, string parameters_string, byte[] bytes)
{
long nowTime = workingTime.ElapsedMilliseconds;
while (times[connection_id].Count > 0 && (nowTime - times[connection_id].Peek()) >= PERIOD_IN_MS)
{
times[connection_id].Dequeue();
}
if (times[connection_id].Count >= MAX_TRANSACTIONS_PER_PERIOD)
{
connectionId).My initial version:
private const int MAX_TRANSACTIONS_PER_PERIOD = 80;
private const int PERIOD_IN_MS = 1000;
private Queue[] times = new Queue[10]
{
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100)
};
private int ExecTransWithStats(int connection_id, string name, string parameters_string, byte[] bytes)
{
DateTime nowTime = DateTime.Now;
while (times[connection_id].Count > 0 && (nowTime - times[connection_id].Peek()).TotalMilliseconds >= PERIOD_IN_MS)
{
times[connection_id].Dequeue();
}
if (times[connection_id].Count >= MAX_TRANSACTIONS_PER_PERIOD)
{
Thread.Sleep(PERIOD_IN_MS - (int) (nowTime - times[connection_id].Dequeue()).TotalMilliseconds);
}
times[connection_id].Enqueue(DateTime.Now);
return ExecTrans(connection_id, name, parameters_string, bytes);
}I've decided to replace
DateTime with Stopwatch just because I don't need to store entire Date. I only need to store how many milliseconds elapsed:```
private const int MAX_TRANSACTIONS_PER_PERIOD = 80;
private const int PERIOD_IN_MS = 1000;
private Queue[] times = new Queue[10]
{
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100),
new Queue(100)
};
private Stopwatch workingTime = Stopwatch.StartNew();
private int ExecTransWithStats(int connection_id, string name, string parameters_string, byte[] bytes)
{
long nowTime = workingTime.ElapsedMilliseconds;
while (times[connection_id].Count > 0 && (nowTime - times[connection_id].Peek()) >= PERIOD_IN_MS)
{
times[connection_id].Dequeue();
}
if (times[connection_id].Count >= MAX_TRANSACTIONS_PER_PERIOD)
{
Solution
StopWatch is definitely better for timing stuff, but the semantics of the two versions are different. With DateTime you have this:private int ExecTransWithStats(int connection_id, string name, string parameters_string, byte[] bytes)
{
DateTime nowTime = DateTime.Now;
...and with
StopWatch you have that:private Stopwatch workingTime = Stopwatch.StartNew();
private int ExecTransWithStats(int connection_id, string name, string parameters_string, byte[] bytes)
{
long nowTime = workingTime.ElapsedMilliseconds;
...Bug?
The stopwatch starts as soon as the instance is created, it looks like you're misusing the stopwatch.
long nowTime = workingTime.ElapsedMilliseconds;That's not how a stopwatch works. That will give you the number of milliseconds elapsed between the instantiation of your class and the moment
ExecTransWithStats gets called. I doubt this is what you are expecting.Code Snippets
private int ExecTransWithStats(int connection_id, string name, string parameters_string, byte[] bytes)
{
DateTime nowTime = DateTime.Now;
...private Stopwatch workingTime = Stopwatch.StartNew();
private int ExecTransWithStats(int connection_id, string name, string parameters_string, byte[] bytes)
{
long nowTime = workingTime.ElapsedMilliseconds;
...long nowTime = workingTime.ElapsedMilliseconds;Context
StackExchange Code Review Q#6750, answer score: 6
Revisions (0)
No revisions yet.