h-opc: DA - Subscription does not report data change of tags if there is a rapidly changing tag within its monitored tag list
I have a situation where I have two tags, the latter is fast changing.
The client “sees” the change of the rapidly updating tag, but any change to the earlier added tag is not being broadcast (or sometimes only rarely) by the Subscription.
If I reverse the order in which the tags are added, changes in both tags are reported as expected.
Here is my code:
public T AddItem<T>(long subscriptionHandle, long clientHandle, string tagName, Action<T, T, T, bool, Action> callback)
{
//
// Find node read from cache or create
var node = FindNode(tagName);
if (node != null)
{
//
// Find subscription (group referenced by subscriptionHandle)
var sub = FindSubscription(subscriptionHandle);
try
{
if (sub == null)
{
sub = AddSubscription<OpcDa.Subscription>(subscriptionHandle.ToString(CultureInfo.InvariantCulture), subscriptionHandle, 0);
}
Opc.Da.Item item = null;
if (clientHandle < 0)
{
if (sub.Items.Count() > 0)
{
item = sub.Items.FirstOrDefault(m => Practicon.Utilities.Strs.StringsEqual(m.ItemName, tagName));
if (item == null)
{
clientHandle = (long)sub.Items.Max(i => i.ClientHandle) + 1;
}
else
{
clientHandle = (long)item.ClientHandle;
}
}
else
{
clientHandle = 0;
}
}
else
{
//
// Item already monitored?
item = sub.Items.FirstOrDefault(m => (long)m.ClientHandle == clientHandle);
}
try
{
if (item == null)
{
item = new OpcDa.Item { ItemName = tagName, ClientHandle = clientHandle };
sub.AddItems(new[] { item });
// I have to start a new thread here because unsubscribing
// the subscription during a datachanged event causes a deadlock
Action unsubscribe = () => new Thread(o =>
{
try
{
_server.CancelSubscription(sub);
}
catch (Exception ex)
{
}
}
).Start();
sub.DataChanged += (handle, requestHandle, values) =>
{
Task.Factory.StartNew(() =>
{
T casted;
TryCastResult(values[0].Value, out casted);
callback((T)casted, (T)handle, (T)values[0].ClientHandle, values[0].Quality == OpcDa.Quality.Good, unsubscribe);
});
};
sub.SetEnabled(true);
}
}
catch (Exception ex)
{
LogMessage(String.Format("DA AddItem.2 Tag : {0}", tagName), ex);
}
return (T)(object)item;
}
catch (Exception ex)
{
LogMessage(String.Format("DA AddItem.3 Tag : {0}", tagName), ex);
}
}
return default(T);
}
If I place a breakpoint inside the anonymous DataChange method, it is NOT called whenever the earlier (i.e. not the rapidly changing) tag is changed. It’s almost as if quickly changing tag overrides the other tag’s notification. This is not restricted to just two tags - whenever I have a group of tags followed by a rapidly changing one, these tags do not broadcast datachange events.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 19 (11 by maintainers)
For multiline codeuse three of these: `