2014-10-09 2 views
0

Я использую OpcNetApi для связи с кеппором. Я пытаюсь прочитать некоторые значения из kepware (более 40 значений). Однако когда моя программа выполняет метод чтения opc-сервера, он ждет около 10 секунд, чтобы прочитать значения, которые я хочу. Это слишком. Я не хочу, чтобы он так долго ждал. Я хочу, чтобы он выполнял метод чтения в течение 1 секунды, я не знаю, в чем проблема. Почему opc читает значения очень медленно? Есть ли способ сделать это быстрее.OpcNetApi медленное чтение из кепвера

Вот мой OPC класс

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace VestelTest 
{ 
    class clsOPC 
    { 

     private static Opc.Da.Server server = null; 
     private static Opc.Da.SubscriptionState groupState; 
     private static Opc.Da.Subscription group; 

     public clsOPC() 
     { 

     } 

     public static void Connect() 
     { 
      //OpcCom.ServerEnumerator se = new OpcCom.ServerEnumerator(); 
      //Opc.Server[] servers = se.GetAvailableServers(Opc.Specification.COM_DA_20); 
      //Opc.Da.Server server = null; 
      Opc.URL url = new Opc.URL("opcda://localhost/KEPware.KEPServerEX.V4"); 
      OpcCom.Factory fact = new OpcCom.Factory(); 
      server = new Opc.Da.Server(fact, url); 
      server.Connect(); 


      groupState = new Opc.Da.SubscriptionState(); 
      groupState.Name = "Salla"; 
      groupState.Active = false; 
      group = (Opc.Da.Subscription)server.CreateSubscription(groupState); 
     } 

     public static void Read(Opc.Da.Item[] items, Opc.Da.ReadCompleteEventHandler method) 
     { 
      //Opc.Da.ItemValueResult[] sonuclar = group.Read(group.Items); 
      if (group != null) 
      { 
       //server.Subscriptions.Clear(); 
       groupState = new Opc.Da.SubscriptionState(); 
       groupState.Name = "Salla"; 
       groupState.Active = false; 
       server.CancelSubscription(group); 
       group = null; 
       group = (Opc.Da.Subscription)server.CreateSubscription(groupState); 

       items = group.AddItems(items); 

       Opc.IRequest req; 
       group.Read(group.Items, 123, method, out req); 
      } 
      //return sonuclar;  
     } 

     public static Opc.Da.ItemValueResult[] Read(Opc.Da.Item[] items) 
     { 
      Opc.Da.ItemValueResult[] sonuclar = new Opc.Da.ItemValueResult[items.Length]; 
      if (group != null) 
      { 
       //server.Subscriptions.Clear(); 
       groupState = new Opc.Da.SubscriptionState(); 
       groupState.Name = "Salla"; 
       groupState.Active = false; 
       server.CancelSubscription(group); 
       group = null; 
       group = (Opc.Da.Subscription)server.CreateSubscription(groupState); 

       items = group.AddItems(items); 

       //sonuclar = group.Read(group.Items); 

       sonuclar = server.Read(items); 
      } 
      return sonuclar; 
     } 

     public static void Write(Opc.Da.Item[] writeItems, Opc.Da.ItemValue[] writeValues, Opc.Da.WriteCompleteEventHandler method, Opc.Da.ReadCompleteEventHandler methodRead) 
     { 
      if (group != null) 
      { 
       //server.Subscriptions.Clear(); 
       groupState = new Opc.Da.SubscriptionState(); 
       groupState.Name = "Salla"; 
       groupState.Active = false; 
       server.CancelSubscription(group); 
       group = null; 
       group = (Opc.Da.Subscription)server.CreateSubscription(groupState); 

       writeItems = group.AddItems(writeItems); 

       for (int i = 0; i < writeItems.Length; i++) 
       { 
        if (writeValues[i] != null) 
         writeValues[i].ServerHandle = group.Items[i].ServerHandle; 
       } 
       Opc.IRequest req; 

       group.Write(writeValues, 321, method, out req); 
       System.Threading.Thread.Sleep(1000); 
       group.Read(group.Items, 123, methodRead, out req); 
      } 

     } 

     public static void Write(Opc.Da.Item[] writeItems, Opc.Da.ItemValue[] writeValues) 
     { 
      if (group != null) 
      { 
       //server.Subscriptions.Clear(); 
       groupState = new Opc.Da.SubscriptionState(); 
       groupState.Name = "Salla"; 
       groupState.Active = false; 
       server.CancelSubscription(group); 
       group = null; 
       group = (Opc.Da.Subscription)server.CreateSubscription(groupState); 

       writeItems = group.AddItems(writeItems); 

       for (int i = 0; i < writeItems.Length; i++) 
       { 
        if (writeValues[i] != null) 
         writeValues[i].ServerHandle = group.Items[i].ServerHandle; 
       } 
       Opc.IRequest req; 

       group.Write(writeValues); 
      } 
     } 

     public static void Disconnect() 
     { 
      server.Disconnect(); 
     } 

     static void ReadCompleteCallback(object clientHandle, Opc.Da.ItemValueResult[] results) 
     { 
      Console.WriteLine("Read completed"); 
      foreach (Opc.Da.ItemValueResult readResult in results) 
      { 
       Console.WriteLine("\t{0}\tval:{1}", readResult.ItemName, readResult.Value); 
      } 
      Console.WriteLine(); 
     } 

     static void WriteCompleteCallback(object clientHandle, Opc.IdentifiedResult[] results) 
     { 
      Console.WriteLine("Write completed"); 
      foreach (Opc.IdentifiedResult writeResult in results) 
      { 
       Console.WriteLine("\t{0} write result: {1}", writeResult.ItemName, writeResult.ResultID); 
      } 
      Console.WriteLine(); 
     } 

    } 
} 

Я использую его, как это;

int deviceID = vChannelDevice[i].device.ID; 
         var vAdres = (from adres in d.tblAddress join groupp in d.tblGroup on adres.GroupID equals groupp.ID join device in d.tblDevice on groupp.DeviceID equals device.ID where device.ID == deviceID select new { adres, groupp, device }).ToList(); 
         if (vAdres.Count > 0) 
         { 
          Opc.Da.Item[] valueItems = new Opc.Da.Item[vAdres.Count]; 
          for (int j = 0; j < vAdres.Count; j++) 
          { 
           valueItems[j] = new Opc.Da.Item(); 
           valueItems[j].ItemName = vChannelDevice[i].channel.Ad + "." + vChannelDevice[i].device.Ad + "." + vAdres[j].groupp.Ad + "." + vAdres[j].adres.Ad; 
          } 
          Opc.Da.ItemValueResult[] valueResults = new Opc.Da.ItemValueResult[vAdres.Count]; 
          if (backgroundWorker1.CancellationPending) 
          { 
           e.Cancel = true; 
           return; 
          } 
          valueResults = clsOPC.Read(valueItems); 
          for (int j = 0; j < vAdres.Count; j++) 
          { 
           if (valueResults[j] != null) 
           { 
            if (valueResults[j].Value != null) 
            { 
             Kaydet(vAdres[j].adres.ID, Convert.ToDouble(valueResults[j].Value), donguTarih); 
            } 
           } 
          } 
         } 

линия valueResults = clsOPC.Read(valueItems); ждет слишком много

+0

Где в 'Read()' метод имеет место пауза? Это на линии 'sonuclar = server.Read (items);'? – DonBoitnott

+0

да это правильно. – MOD

+0

Тогда кажется ясным, что это ответ сервера, который отстает, а не ваш запрос на значения. – DonBoitnott

ответ

0

Ну я знаю, что это поздно .. Вы отменяете подписку - это требует поездки. Вы снова воссоздаете время подписки. Затем вы решили добавить к нему элементы, а затем прочитать его.

Если вы хотите очистить подписку - почему бы не выполнить это после того, как вы вернете полностью прочитанное сообщение. Тогда вам не нужно тратить время на обслуживание серверов Opc во время запроса на чтение.

Ваш код выглядит так:

if (group != null) 
    { 
     //server.Subscriptions.Clear(); 
     groupState = new Opc.Da.SubscriptionState(); 
     groupState.Name = "Salla"; 
     groupState.Active = false; 
     server.CancelSubscription(group); 
     group = null; 
     group = (Opc.Da.Subscription)server.CreateSubscription(groupState); 

     items = group.AddItems(items); 

     Opc.IRequest req; 
     group.Read(group.Items, 123, method, out req); 
    }