Here is the situation.
What I work with: - ASP.NET MVC 4 Web API - IIS 7.0 for hosting the application - C #
I have a web API that receives performance data from remote computers on an intranet, and I am testing the API call through URL calls, and this returns JSON. However, it must complete execution first before returning JSON. So, for example, if I return to performance monitoring within 10 seconds, I will have to wait 10 seconds before displaying all displayed values.
I want to do this live so that it returns a value when it reads the performance counter every second and displays it in JSON, rather than expecting everything to be restored and then listing everything at once. I am trying to use the YIELD keyword to accomplish this, but it still does not work. JSON is not displayed in the browser until the method is fully completed.
Here is the code for the repository method and for the coordination controller action:
From LogDBRepository.cs:
public IEnumerable<DataValueInfo> LogTimedPerfDataLive(string macName, string categoryName, string counterName,
string instanceName, string logName, long? seconds)
{
iModsDBRepository modsDB = new iModsDBRepository();
List<MachineInfo> theMac = modsDB.GetMachineByName(macName);
if (theMac.Count == 0)
yield break;
else if (instanceName == null)
{
if (!PerformanceCounterCategory.Exists(categoryName, macName) ||
!PerformanceCounterCategory.CounterExists(counterName, categoryName, macName))
{
yield break;
}
}
else if (instanceName != null)
{
if (!PerformanceCounterCategory.Exists(categoryName, macName) ||
!PerformanceCounterCategory.CounterExists(counterName, categoryName, macName) ||
!PerformanceCounterCategory.InstanceExists(instanceName, categoryName, macName))
{
yield break;
}
}
else if (logName == null)
{
yield break;
}
List<LogInfo> checkDuplicateLog = this.GetSingleLog(logName);
if (checkDuplicateLog.Count > 0)
{
yield break;
}
PerformanceCounterCategory category = new PerformanceCounterCategory(categoryName, theMac[0].MachineName);
if (category.CategoryName == null || category.MachineName == null)
{
yield break;
}
List<LogInfo> logIt = new List<LogInfo>();
if (category.CategoryType != PerformanceCounterCategoryType.SingleInstance)
{
List<InstanceInfo> instances = modsDB.GetInstancesFromCatMacName(theMac[0].MachineName, category.CategoryName);
foreach (InstanceInfo inst in instances)
{
if (!category.InstanceExists(inst.InstanceName))
{
continue;
}
else if (inst.InstanceName.Equals(instanceName, StringComparison.OrdinalIgnoreCase))
{
PerformanceCounter perfCounter = new PerformanceCounter(categoryName, counterName,
inst.InstanceName, theMac[0].MachineName);
string data = "";
List<UserInfo> currUser = this.GetUserByName(WindowsIdentity.GetCurrent().Name);
string timeStarted = DateTime.Now.ToString("MM/dd/yyyy - h:mm:ss tt");
List<string> dataValues = new List<string>();
for (int i = 0; i < seconds; i++)
{
data = "Value " + i + ": " + perfCounter.NextValue().ToString();
DataValueInfo datItUp = new DataValueInfo
{
Value = data
};
yield return datItUp;
dataValues.Add(data);
Thread.Sleep(1000);
}
string timeFinished = DateTime.Now.ToString("MM/dd/yyyy - h:mm:ss tt");
Log log = new Log
{
LogName = logName,
CounterName = perfCounter.CounterName,
InstanceName = perfCounter.InstanceName,
CategoryName = perfCounter.CategoryName,
MachineName = perfCounter.MachineName,
TimeStarted = timeStarted,
TimeFinished = timeFinished,
PerformanceData = string.Join(",", dataValues),
UserID = currUser[0].UserID
};
this.CreateLog(log);
break;
}
}
}
else
{
PerformanceCounter perfCounter = new PerformanceCounter(categoryName, counterName,
"", theMac[0].MachineName);
string data = "";
List<UserInfo> currUser = this.GetUserByName(WindowsIdentity.GetCurrent().Name);
string timeStarted = DateTime.Now.ToString("MM/dd/yyyy - h:mm:ss tt");
List<string> dataValues = new List<string>();
for (int i = 0; i < seconds; i++)
{
data = "Value " + i + ": " + perfCounter.NextValue().ToString();
DataValueInfo datItUp = new DataValueInfo
{
Value = data
};
yield return datItUp;
dataValues.Add(data);
Thread.Sleep(1000);
}
string timeFinished = DateTime.Now.ToString("MM/dd/yyyy - h:mm:ss tt");
Log log = new Log
{
LogName = logName,
CounterName = perfCounter.CounterName,
InstanceName = perfCounter.InstanceName,
CategoryName = perfCounter.CategoryName,
MachineName = perfCounter.MachineName,
TimeStarted = timeStarted,
TimeFinished = timeFinished,
PerformanceData = string.Join(",", dataValues),
UserID = currUser[0].UserID
};
this.CreateLog(log);
}
}
From LogController.cs:
[AcceptVerbs("GET", "POST")]
public IEnumerable<DataValueInfo> Log_Perf_Data(string machine_name, string category_name, string counter_name, string instance_name,
string log_name, long? seconds, string live, string enforceQuery)
{
LogController.CheckUser();
if (machine_name != null && category_name != null && counter_name != null && log_name != null && seconds.HasValue && enforceQuery == null)
{
List<DataValueInfo> dataVal = logDB.LogTimedPerfDataLive(machine_name, category_name, counter_name, instance_name,
log_name, seconds).ToList();
logDB.SaveChanges();
foreach (var val in dataVal)
yield return val;
}
yield break;
}
Thank you for your time and attention.