Reputation: 95
i have a measurement-instrument that creates measurements for a specified time. During this time i have to fetch the measurements from the internal memory to prevent an overflow. Currently i have this:
public int FetchDatalog(int Time_s, double Period, out int Count, ref double[] Results)
{
Count = 0;
try
{
DateTime timeout = DateTime.UtcNow.AddSeconds(Time_s);
double[] values;
while (DateTime.UtcNow < timeout)
{
values = //here is the command to tell the instrument to return 10 results
Count = values.Count();
Thread.Sleep(500);
//HERE IS SOMETHING MISSING <-----
}
}
return 0;
}
So i have a function that reads in a loop always 10 results from a instruments until a specified time is over. During the loops the read data must be merged.
At the arrow-marked position i need now something that merges the 10 values together and finally returns all merged values back in results.
How can i do this with unknown length?
(As extra problem is: The 10 results can be "up to 10" results. Sometimes less then 10, so i could change here also if needed to only read 1 value, but this would make it slowlier.
Thanks for all help
Added comment here so its readable - Sayse
I mean merge:
loop1: values[]=1,2,3,4,5,6,7,8,9,0;
loop2: values[]=11,22,33,44,55,66,77,88,99,11
loop3: values[]=111,222,333,444,555,666,777,888,999,111
This three values should finally return in parameter result as
result[]=1,2,3,4,5,6,7,8,9,0,11,22,33,44,55,66,
77,88,99,11,111,222,333,444,555,666,777,888,999,111
So they should be put together to a bigger array.
Upvotes: 0
Views: 292
Reputation: 10515
If you need to maintain the array as your parameter type for some reason, you could just create a list, append to the list, then return the result:
public int FetchDatalog(int Time_s, double Period, out int Count, ref double[] Results)
{
Count = 0;
List<double> existing = new List<double>(Results);
try
{
DateTime timeout = DateTime.UtcNow.AddSeconds(Time_s);
double[] values;
while (DateTime.UtcNow < timeout)
{
values = //here is the command to tell the instrument to return 10 results
Count += values.Length;
Thread.Sleep(500);
existing.AddRange(values);
}
}
finally
{
Results = existing.ToArray();
}
return 0;
}
If I had my druthers, it'd look more like:
public int FetchDatalog(int readLength, double sleepPeriod, List<double> results)
{
var readingsCount = 0;
try
{
var timeout = DateTime.UtcNow.AddSeconds(readLength);
while (DateTime.UtcNow < timeout)
{
values = RetrieveBufferedSensorReadings(10);
readingsCount += values.Length;
results.AddRange(values);
Thread.Sleep(sleepPeriod);
}
return readingsCount;
}
catch (Exception e) //<-- this should be special purpose based on sleep/read failures
{
throw; //Return -1 or the like if you must... but ew.
}
}
You could even look at using the newer async
functionality in 4.0 as Thread.Sleep
is generally considered bad.
EDIT:
Based on your last comment, it seems you are doing this:
double[] Results = new double[100];
ret = GetData(TimeSec, out Count, ref Results);
I feel this is poor structure, but we'll go with it as a learning tool:
public int GetData(int Time_s, out int Count, ref double[] Results)
{
var lengthIncrement = 100;
Count = 0;
try
{
DateTime timeout = DateTime.UtcNow.AddSeconds(Time_s);
double[] values;
while (DateTime.UtcNow < timeout)
{
values = //here is the command to tell the instrument to return 10 results
//Before copying over value, make sure we won't overflow
//If we will, extend array
if (Count + values.Length > Results.Length) {
var temp = new double[Results.Length + lengthIncrement];
Array.Copy(Results, temp, Count);
Results = temp;
}
Array.Copy(values, 0, Results, Count, values.Length);
Count += values.Length;
Thread.Sleep(500);
}
}
return 0;
}
Allow me to reiterate what many other's are saying... The following is a much better design:
var results = new List<double>();
ret = GetData(TimeSec, out Count, results);
Upvotes: 1