/// <summary> /// IOPCAsyncIO3::RefreshMaxAge - Force a callback to IOPCDataCallback::OnDataChange for all active items in the group /// (whether they have changed or not). Inactive items are not included in the callback. /// </summary> public void RefreshMaxAge( int dwMaxAge, int dwTransactionID, out int pdwCancelID) { pdwCancelID = 0; // get callback object - error if missing. IOPCDataCallback callback = (IOPCDataCallback)GetCallback(typeof(IOPCDataCallback).GUID); if (callback == null) { throw ComUtils.CreateComException(ResultIds.CONNECT_E_NOCONNECTION); } try { // build list of values to read. ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); lock (m_lock) { if (m_subscription == null) throw ComUtils.CreateComException(ResultIds.E_FAIL); foreach (Item itemToRead in m_items.Values) { // check if active. if (!m_active || !itemToRead.Active) { continue; } ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = itemToRead.MonitoredItem.ResolvedNodeId; nodeToRead.AttributeId = Attributes.Value; // needed to correlate results to input. nodeToRead.Handle = itemToRead; nodesToRead.Add(nodeToRead); } // check if nothing to read. if (nodesToRead.Count == 0) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } // read values from server. pdwCancelID = Utils.IncrementIdentifier(ref m_nextHandle); m_transactions[pdwCancelID] = new AsyncReadTransaction(dwTransactionID, nodesToRead, true); } m_session.BeginRead( null, dwMaxAge, TimestampsToReturn.Both, nodesToRead, new AsyncCallback(OnReadComplete), pdwCancelID); } catch (Exception e) { Utils.Trace(e, "Error refreshing group."); throw ComUtils.CreateComException(e); } }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// #region IOPCAsyncIO3 Members /// <summary> /// IOPCAsyncIO3::ReadMaxAge - Reads one or more values, qualities and timestamps for the items specified. /// This is functionally similar to the OPCSyncIO::Read method except it is asynchronous /// and no source is specified (DEVICE or CACHE). /// </summary> public void ReadMaxAge( int dwCount, int[] phServer, int[] pdwMaxAge, int dwTransactionID, out int pdwCancelID, out System.IntPtr ppErrors) { pdwCancelID = 0; // validate arguments. if (dwCount == 0 || phServer == null || pdwMaxAge == null || dwCount != phServer.Length) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } // get callback object - error if missing. IOPCDataCallback callback = (IOPCDataCallback)GetCallback(typeof(IOPCDataCallback).GUID); if (callback == null) { throw ComUtils.CreateComException(ResultIds.CONNECT_E_NOCONNECTION); } try { int[] errors = new int[dwCount]; // build list of values to read. ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); // use the minimum max age for all items. int maxAge = Int32.MaxValue; lock (m_lock) { if (m_subscription == null) throw ComUtils.CreateComException(ResultIds.E_FAIL); for (int ii = 0; ii < dwCount; ii++) { Item itemToRead = null; if (!m_items.TryGetValue(phServer[ii], out itemToRead)) { errors[ii] = ResultIds.E_INVALIDHANDLE; continue; } ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = itemToRead.MonitoredItem.ResolvedNodeId; nodeToRead.AttributeId = Attributes.Value; // needed to correlate results to input. nodeToRead.Handle = itemToRead; nodesToRead.Add(nodeToRead); // update max age. if (maxAge > pdwMaxAge[ii]) { maxAge = pdwMaxAge[ii]; } } // create transaction. if (nodesToRead.Count > 0) { pdwCancelID = Utils.IncrementIdentifier(ref m_nextHandle); m_transactions[pdwCancelID] = new AsyncReadTransaction(dwTransactionID, nodesToRead, false); } } // read values from server. if (nodesToRead.Count > 0) { m_session.BeginRead( null, maxAge, TimestampsToReturn.Both, nodesToRead, new AsyncCallback(OnReadComplete), pdwCancelID); } // marshal error codes. ppErrors = ComUtils.GetInt32s(errors); } catch (Exception e) { Utils.Trace(e, "Error reading items."); throw ComUtils.CreateComException(e); } }