/// <summary> /// Calculates and returns the statistic data. /// It is recommended to call this function every 1s or 10s and put the received data into a DataSet Table. /// It is not mandatory to use this, but the statistic data will be collected anyway. /// </summary> /// <param name="xmlTable">XML structure that is compatible with System.Data.DataSet</param> /// <param name="additionalText">Some additional information. May be displayed under the table.</param> public void GetStatistics(out string xmlTable, out string additionalText) { try { StringBuilder sb1 = new StringBuilder(); StringBuilder sb2 = new StringBuilder(); sb1.AppendLine("<Table>"); intervalStopwatch.Stop(); lock (lockObj) { foreach (KeyValuePair <int, StatData> item in statDataDict) { StatData v = item.Value; sb1.AppendLine("<Element>"); sb1.AppendFormat("<Thread>{0}:{2}{1}</Thread>", item.Key, v.Name, Environment.NewLine); sb1.AppendFormat("<Scope>Total{0}Actual</Scope>", Environment.NewLine); sb1.AppendFormat("<TxBytes>{0}B{2}{1}B</TxBytes>{2}", CExp(v.TotalTxBytes), CExp(v.TotalTxBytes - v.OldTxBytes), Environment.NewLine); sb1.AppendFormat("<RxBytes>{0}B{2}{1}B</RxBytes>{2}", CExp(v.TotalRxBytes), CExp(v.TotalRxBytes - v.OldRxBytes), Environment.NewLine); sb1.AppendFormat("<TxSpeed>{0}B{2}{1}B/s</TxSpeed>{2}", CExp(v.TotalTxBytes / totalTimeStopwatch.Elapsed.TotalSeconds), CExp((v.TotalTxBytes - v.OldTxBytes) / intervalStopwatch.Elapsed.TotalSeconds), Environment.NewLine); sb1.AppendFormat("<RxSpeed>{0}B/s{2}{1}B/s</RxSpeed>{2}", CExp(v.TotalRxBytes / totalTimeStopwatch.Elapsed.TotalSeconds), CExp((v.TotalRxBytes - v.OldRxBytes) / intervalStopwatch.Elapsed.TotalSeconds), Environment.NewLine); sb1.AppendFormat("<ComTime>{0}s{2}{1}s</ComTime>{2}", CExp(v.ComTimeStw.Elapsed.TotalSeconds), CExp((v.ComTimeStw.Elapsed - v.OldComTime).TotalSeconds), Environment.NewLine); sb1.AppendFormat("<WaitTime>{0}s{2}{1}s</WaitTime>{2}", CExp(v.WaitTimeStw.Elapsed.TotalSeconds), CExp((v.WaitTimeStw.Elapsed - v.OldWaitTime).TotalSeconds), Environment.NewLine); sb1.AppendFormat("<ComUsage>{0:N1} %{2}{1:N1} %</ComUsage>{2}", 100.0 / totalTimeStopwatch.Elapsed.TotalSeconds * v.ComTimeStw.Elapsed.TotalSeconds, 100.0 / intervalStopwatch.Elapsed.TotalSeconds * (v.ComTimeStw.Elapsed - v.OldComTime).TotalSeconds, Environment.NewLine); sb1.AppendFormat("<TxFrames>{0}{2}{1}</TxFrames>{2}", v.TotalTxFrames, v.TotalTxFrames - v.OldTxFrames, Environment.NewLine); sb1.AppendFormat("<RxFrames>{0}{2}{1}</RxFrames>{2}", v.TotalRxFrames, v.TotalRxFrames - v.OldRxFrames, Environment.NewLine); sb1.AppendFormat("<CrcErrors>{0}{2}{1}</CrcErrors>{2}", v.TotalCrcErrors, v.TotalCrcErrors - v.OldCrcErrors, Environment.NewLine); sb1.AppendLine("</Element>"); v.SetOldValues(); } } sb1.AppendLine("</Table>"); xmlTable = sb1.ToString(); sb2.AppendFormat("Actual Measuring Interval: {0:N1} s{1}", intervalStopwatch.Elapsed.TotalSeconds, Environment.NewLine); sb2.AppendFormat("Total Measuring Time: {0:N0} s{1}", totalTimeStopwatch.Elapsed.TotalSeconds, Environment.NewLine); additionalText = sb2.ToString(); intervalStopwatch.Restart(); } catch (Exception ex) { xmlTable = ""; additionalText = ex.Message; } }