- Posts: 11
- Thank you received: 0
Online Forums
Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.
Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.
Do not use the Contact page for technical issues.
- Forum
- Discussions
- QuickOPC-Classic in .NET
- Reading, Writing, Subscriptions, Property Access
- Polling Functionality For Slow Updating OPC Items
Polling Functionality For Slow Updating OPC Items
Thank you for your suggestions, however, we believe that polling with your client in the way we have been doing it is, as you have described it, an anti-pattern. Therefore, we will be using the normal subscription method along with our own internal polling system without contacting the OPC Server.
Kind regards,
Bishop.
Please Log in or Create an account to join the conversation.
thank you for more information.
There is nothing in it that implies that the long time/timeout taken by Read is caused either by the client, or the server. It needs to be determined first. A statement that would point to the client as the likely cause might look like "We have used some other OPC client doing a similar pattern of operations on the same OPC server, and it does not exhibit the same problem".
Will you be willing to deploy an OPC Analyzer and take a trace of OPC communications? (kb.opclabs.com/How_to_use_OPC_Analyzer , kb.opclabs.com/Collecting_information_for_troubleshooting )
I also think that there are other imprecise statement or conclusions in your reply.
Re "OPC is famous for its speed.": Maybe, but that just means that OPC does not, by itself, introduce unnecessary slowness, if everything is implemented properly. OPC does not *guarantee* speed just by the fact that you have somewhere OPC in the app (the fact that is you are observing the validity of this statement right now, that's why are you raising a tech support issue here).
Repeated Reads are one of the anti-patterns in OPC, and there are reasons for that. Subscriptions should be used whenever possible. You have somewhat touched on one of reasons for that: If you are reading multiple items in one call, their results are returned together. If you are reading 100 items, and the server needs 1 millisecond for 99 items, and 15 seconds for one of the items, the whole operation will take 15 seconds. There is absolutely nothing any OPC client can do to change this Read behavior. I am not saying that this is happening in your case, but it might be. We just do not know yet. And, if you wanted to resolve this by doing 100 individual Reads instead, then it might work too, but you may hit other problems: The roundtrips for each operation will add up, so the total time will be much longer than that single Read with 100 items.
Regards
Please Log in or Create an account to join the conversation.
So to answer your questions:
"What leads to you to think that the problem is somehow related to the OPC client side of things?"
-below is a code snippet from our Quartz job. Note that I have placed timings around notable events and the event of interest is 3. This is the time taken for the ReadMultipleItems to return an array of DAVtqResult.
-below the code snippet you will see the output. Note that several jobs fire with events 1, 2, 4 and 5 returning negligible timings (+-10ms). Event 3, however, returns timings of over 10000ms and this is what leads me to believe that "...the problem is somehow related to the OPC client side of things".
Code:
sw.Start();
var test = (List<(int, string, TypeCode)>)value;
DAItemDescriptor[] argumentArray = new DAItemDescriptor[test.Count()];
IList<(DAVtqResult, int, TypeCode)> blo = new List<(DAVtqResult, int, TypeCode)>();
sw.Stop();
await Console.Error.WriteLineAsync($"1: {sw.ElapsedMilliseconds}");
sw.Restart();
for (int i = 0; i < test.Count(); i++)
{
argumentArray[i] = new DAItemDescriptor(test.ElementAt(i).Item2);
}
sw.Stop();
await Console.Error.WriteLineAsync($"2: {sw.ElapsedMilliseconds}");
sw.Restart();
ServerDescriptor serverDescriptor = new ServerDescriptor(MachineName, SourceName);
var bla = _CollectorSource._EasyDAClient.ReadMultipleItems(serverDescriptor, argumentArray);
sw.Stop();
await Console.Error.WriteLineAsync($"3: {sw.ElapsedMilliseconds}");
sw.Restart();
for (int i = 0; i < test.Count(); i++)
{
blo.Add((bla.ElementAt(i), test.ElementAt(i).Item1, test.ElementAt(i).Item3));
}
sw.Stop();
await Console.Error.WriteLineAsync($"4: {sw.ElapsedMilliseconds}");
sw.Restart();
var options = new ParallelOptions()
{
MaxDegreeOfParallelism = 2
};
Parallel.ForEach(blo, options, i =>
{
DAVtqResultsToPointModel(i);
});
sw.Stop();
await Console.Error.WriteLineAsync($"5: {sw.ElapsedMilliseconds}");
sw.Restart();
Output:
1: 5
1: 5
1: 3856
1: 5
1: 0
2: 0
1: 0
2: 0
1: 0
2: 0
1: 0
2: 0
1: 0
2: 0
1: 0
2: 0
1: 0
2: 0
1: 0
2: 0
1: 0
2: 0
1: 0
2: 0
3: 11459
4: 1
3: 9473
4: 0
5: 6
5: 8
3: 10489
4: 0
5: 5
3: 8530
4: 0
3: 7546
4: 0
3: 6567
4: 0
5: 36
5: 15
1: 0
5: 2
1: 0
2: 0
2: 0
1: 0
2: 0
1: 0
2: 0
1: 0
2: 0
1: 0
2: 0
3: 16170
4: 0
3: 11582
5: 1
3: 10175
3: 9176
"Or is it just a guess?"
-No
Finally, with respect to your last comment:
"Because, without an information pointing to the client, it can just as well be the OPC server simply taking so much time to fulfill the request."
OPC is famous for its speed. If we are wanting to read values on site for say 10000 values every 1000ms, all we want is to know what the last known value was for each tag as fast as possible. Surely the client should have safe guards to stop requests taking longer than a certain time (which I alluded to in my previous reply about the EasyDAClient.InstanceParameters.Timeouts.ReadItem). If not this setting, there should be others to ensure that the majority of tag values are not jeopardised based on a single tag on the server taking longer than usual to return a new value or a "Good/Succeeded" result.
We would ideally like the client to resolve this for us as seamlessly as possible.
Regards,
Bishop.
Please Log in or Create an account to join the conversation.
What leads to you to think that the problem is somehow related to the OPC client side of things? (It may be - but I am asking about the thought process here). Or is it just a guess?
Because, without an information pointing to the client, it can just as well be the OPC server simply taking so much time to fulfill the request.
Regards
Please Log in or Create an account to join the conversation.
Please Log in or Create an account to join the conversation.
for start, which QuickOPC version are you using please?
Thank you
Please Log in or Create an account to join the conversation.
My team and I are once again in need of your expert help. We have recently changed our scheduling system for polling our OPC server, due to design constraints. We are currently using the Quartz scheduler for sorting tags into different polling interval cycles.
What we have noticed is that the polling of a moderate number of tags (1-10) within each Quartz job tends to run fine, however, once the number grows large (100 tags) the `ReadMultipleItems` method begins to take over 10 seconds to return.
Now I have been reading through your online forums and have explored a number of avenues but nothing has seemed to work. I have also tried setting the `EasyDAClient.InstanceParameters.Timeouts.ReadItem` value to match our lowest polling interval (1000ms). The only difference now is that the `ReadMultipleItems` call returns but with no value because the `DAVtq` value has not "succeeded".
Please, all I want to do is make a call to an OPC server and return the last known value for a set of items as fast as humanly possible.
yours sincerely,
Bishop.
Please Log in or Create an account to join the conversation.
I will start from the end of your post.
Event Pull Mechanism is not related to the core of your question at all. It is just a different mechanism for delivering the *same* events. So instead of getting called (the "true" events), your code pulls them from the queue. But you will get precisely the same events either way.
To the actual question: If I understand it correctly, the answer is No; to achieve that, you would not use Subscriptions, you would use repeated Reads.
I know that some scenarios require this. For example, historians/loggers want to know that the value has stayed the same, but it has been collected again - so that it has a new timestamp. But the RequestedUpdateRate in OPC DA is really doing what you have described, setting a limit on the update rate. Unless the server effectively violates the spec by sending out more updates, and with the same value, the Reads are the only way to do it.
The newer OPC Unified Architecture has more options in this respect.
Best regards
Please Log in or Create an account to join the conversation.
We would then effectively call this data collection On Change with a limit on the frequency at which we would like data to be collected. Is it possible to have the opposite functionality? i.e. if a tag updates every 5 seconds on the OPC Server, and we would like to poll at a rate of 1 second, is there a way that we could acquire the same value 5 times for the slowly changing tag (every 1 second)? Can we do this without the Event Pull Mechanism ?
Please Log in or Create an account to join the conversation.
- Forum
- Discussions
- QuickOPC-Classic in .NET
- Reading, Writing, Subscriptions, Property Access
- Polling Functionality For Slow Updating OPC Items