public void ModifyMonitoredItems(
OperationContext context,
TimestampsToReturn timestampsToReturn,
MonitoredItemModifyRequestCollection itemsToModify,
out MonitoredItemModifyResultCollection results,
out DiagnosticInfoCollection diagnosticInfos)
{
if (context == null) throw new ArgumentNullException("context");
if (itemsToModify == null) throw new ArgumentNullException("itemsToModify");
int count = itemsToModify.Count;
// allocate results.
bool diagnosticsExist = false;
results = new MonitoredItemModifyResultCollection(count);
diagnosticInfos = null;
if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
{
diagnosticInfos = new DiagnosticInfoCollection(count);
}
// build list of items to modify.
List<IMonitoredItem> monitoredItems = new List<IMonitoredItem>(count);
List<ServiceResult> errors = new List<ServiceResult>(count);
List<MonitoringFilterResult> filterResults = new List<MonitoringFilterResult>(count);
double[] originalSamplingIntervals = new double[count];
bool validItems = false;
lock (m_lock)
{
// check session.
VerifySession(context);
// clear lifetime counter.
ResetLifetimeCount();
for (int ii = 0; ii < count; ii++)
{
filterResults.Add(null);
LinkedListNode<IMonitoredItem> node = null;
if (!m_monitoredItems.TryGetValue(itemsToModify[ii].MonitoredItemId, out node))
{
monitoredItems.Add(null);
errors.Add(StatusCodes.BadMonitoredItemIdInvalid);
// update diagnostics.
if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
{
DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]);
diagnosticsExist = true;
diagnosticInfos.Add(diagnosticInfo);
}
continue;
}
IMonitoredItem monitoredItem = node.Value;
monitoredItems.Add(monitoredItem);
originalSamplingIntervals[ii] = monitoredItem.SamplingInterval;
errors.Add(null);
validItems = true;
// update diagnostics.
if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
{
diagnosticInfos.Add(null);
}
}
}
// update items.
if (validItems)
{
m_server.NodeManager.ModifyMonitoredItems(
context,
timestampsToReturn,
monitoredItems,
itemsToModify,
errors,
filterResults);
}
lock (m_lock)
{
// create results.
for (int ii = 0; ii < errors.Count; ii++)
{
ServiceResult error = errors[ii];
MonitoredItemModifyResult result = null;
if (ServiceResult.IsGood(error))
{
error = monitoredItems[ii].GetModifyResult(out result);
}
if (result == null)
{
result = new MonitoredItemModifyResult();
}
if (error == null)
{
result.StatusCode = StatusCodes.Good;
}
else
{
result.StatusCode = error.StatusCode;
}
// update diagnostics.
if (ServiceResult.IsGood(error))
{
ModifyItemSamplingInterval(originalSamplingIntervals[ii], result.RevisedSamplingInterval, monitoredItems[ii].MonitoringMode);
}
if (filterResults[ii] != null)
{
result.FilterResult = new ExtensionObject(filterResults[ii]);
}
results.Add(result);
if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
{
if (error != null && error.Code != StatusCodes.Good)
{
diagnosticInfos[ii] = ServerUtils.CreateDiagnosticInfo(m_server, context, error);
diagnosticsExist = true;
}
}
}
// clear diagnostics if not required.
if (!diagnosticsExist && diagnosticInfos != null)
{
diagnosticInfos.Clear();
}
// TraceState("ITEMS MODIFIED");
}
}