public OpcStatusCollection DeleteHistory(
            OpcContext context,
            OpcHistoryModificationInfo modificationInfo,
            OpcValueCollection values)
        {
            var results = OpcStatusCollection.Create(OpcStatusCode.Good, values.Count);

            lock (this.syncRoot) {
                for (int index = 0; index < values.Count; index++)
                {
                    var timestamp = OpcHistoryValue.Create(values[index]).Timestamp;
                    var result    = results[index];

                    if (this.History.Contains(timestamp))
                    {
                        var value = this.History[timestamp];
                        this.History.RemoveAt(timestamp);

                        var modifiedValue = value.CreateModified(modificationInfo);
                        this.ModifiedHistory.Add(modifiedValue);
                    }
                    else
                    {
                        result.Update(OpcStatusCode.BadNoEntryExists);
                    }
                }
            }

            return(results);
        }
        public OpcStatusCollection DeleteHistory(
            OpcContext context,
            OpcHistoryModificationInfo modificationInfo,
            DateTime?startTime,
            DateTime?endTime,
            OpcDeleteHistoryOptions options)
        {
            var results = new OpcStatusCollection();

            lock (this.syncRoot) {
                if (options.HasFlag(OpcDeleteHistoryOptions.Modified))
                {
                    this.ModifiedHistory.RemoveRange(startTime, endTime);
                }
                else
                {
                    var values = this.History.Enumerate(startTime, endTime).ToArray();
                    this.History.RemoveRange(startTime, endTime);

                    for (int index = 0; index < values.Length; index++)
                    {
                        var value = values[index];
                        this.ModifiedHistory.Add(value.CreateModified(modificationInfo));

                        results.Add(OpcStatusCode.Good);
                    }
                }
            }

            return(results);
        }
        public OpcStatusCollection DeleteHistory(
            OpcContext context,
            OpcHistoryModificationInfo modificationInfo,
            IEnumerable <DateTime> times)
        {
            var results = OpcStatusCollection.Create(OpcStatusCode.Good, times.Count());

            lock (this.syncRoot) {
                int index = 0;

                foreach (var time in times)
                {
                    var result = results[index++];

                    if (this.History.Contains(time))
                    {
                        var value = this.History[time];
                        this.History.RemoveAt(time);

                        var modifiedValue = value.CreateModified(modificationInfo);
                        this.ModifiedHistory.Add(modifiedValue);
                    }
                    else
                    {
                        result.Update(OpcStatusCode.BadNoEntryExists);
                    }
                }
            }

            return(results);
        }
        static void Main(string[] args)
        {
            var client = new OpcClient("opc.tcp://127.0.0.1:49320");

            client.Security.UserIdentity   = new OpcClientIdentity("Tim", "1qaz2wsx3edc4rfv");
            client.Security.EndpointPolicy = new OpcSecurityPolicy(OpcSecurityMode.SignAndEncrypt, OpcSecurityAlgorithm.Basic256);
            client.Connect();


            // 一次寫取多個Tag
            OpcWriteNode[] wCommands = new OpcWriteNode[] {
                new OpcWriteNode("ns=2;s=Channel2.Device1.Tag1", false),     // 寫 boolean
                new OpcWriteNode("ns=2;s=Channel2.Device1.Tag2", "Test"),    // 寫 sting
                new OpcWriteNode("ns=2;s=Channel2.Device1.Tag3", 8.7),       // 寫 float
                new OpcWriteNode("ns=2;s=Channel2.Device1.Tag3", (ushort)88) // 寫 word
            };
            OpcStatusCollection results = client.WriteNodes(wCommands);

            // 一次讀取多個Tag
            OpcReadNode[] rCommands = new OpcReadNode[] {
                new OpcReadNode("ns=2;s=Channel2.Device1.Tag1"),
                new OpcReadNode("ns=2;s=Channel2.Device1.Tag2"),
                new OpcReadNode("ns=2;s=Channel2.Device1.Tag3"),
                new OpcReadNode("ns=2;s=Channel2.Device1.Tag4")
            };
            IEnumerable <OpcValue> job = client.ReadNodes(rCommands);
            int i = 0;

            foreach (OpcValue value in job)
            {
                Console.WriteLine("ReadNode: {0},\t = {1}", rCommands[i].NodeId, value);
                i++;
            }


            // 訂閱Tag5
            OpcSubscription subscription = client.SubscribeDataChange("ns=2;s=Channel2.Device1.Tag5", HandleDataChanged);

            subscription.PublishingInterval = 1000;
            subscription.ApplyChanges();


            Console.ReadLine();

            client.Disconnect();
        }
        public OpcStatusCollection UpdateHistory(
            OpcContext context,
            OpcHistoryModificationInfo modificationInfo,
            OpcValueCollection values)
        {
            var results = OpcStatusCollection.Create(OpcStatusCode.Good, values.Count);

            lock (this.syncRoot) {
                var expectedDataTypeId = this.Node.DataTypeId;

                for (int index = 0; index < values.Count; index++)
                {
                    var result = results[index];
                    var value  = OpcHistoryValue.Create(values[index]);

                    if (value.DataTypeId == expectedDataTypeId)
                    {
                        if (this.History.Contains(value.Timestamp))
                        {
                            var oldValue = this.History[value.Timestamp];
                            this.History.Replace(value);

                            var modifiedValue = oldValue.CreateModified(modificationInfo);
                            this.ModifiedHistory.Add(modifiedValue);

                            result.Update(OpcStatusCode.GoodEntryReplaced);
                        }
                        else
                        {
                            this.History.Add(value);

                            var modifiedValue = value.CreateModified(modificationInfo);
                            this.ModifiedHistory.Add(modifiedValue);

                            result.Update(OpcStatusCode.GoodEntryInserted);
                        }
                    }
                    else
                    {
                        result.Update(OpcStatusCode.BadTypeMismatch);
                    }
                }
            }

            return(results);
        }