Professional OPC
Development Tools

logos

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.

Hang with Task

More
24 Apr 2014 06:38 #1882 by support
Replied by support on topic Hang with Task<T>
That's great - may I know briefly where it was?

Best regards,
Zbynek Zahradnik

Original Message
From: O.
Sent: Wednesday, April 23, 2014 6:00 PM
To: Zbynek Zahradnik
Subject: I found the error My self

Ignore my previous mail.

> Regards O.

Please Log in or Create an account to join the conversation.

More
24 Apr 2014 06:37 #1881 by support
Replied by support on topic Hang with Task<T>
From: O.
Sent: Wednesday, April 23, 2014 3:18 PM
To: Zbynek Zahradnik
Subject: SV: Problems with hang

Hi again

Tried this but didn't get any avents.

Can you see anything wrong?

>O.

        public async Task<byte> WaitForAsync(string host, string serverName, string tagID, short waitFor, ILog logger)
        {
            EasyDAClient opcComponent = new EasyDAClient();
            opcComponent.Isolated = true;
            opcComponent.InstanceParameters.Mode.AllowAsynchronousMethod = false;
 
            var result = await TryWaitForAsync(opcComponent, host, serverName, tagID, waitFor, logger);
 
            opcComponent.UnsubscribeAllItems();
 
            return 1;
 
        }
 
 
 	private Task<T> TryWaitForAsync<T>(EasyDAClient opcComponent, string host, string serverName, string tagID, T waitFor, ILog logger) where T:struct
        {
            TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
 
 
            opcComponent.ItemChanged += (s, e) =>
            {
                try
                {
                    if (e.Vtq != null)
                    {
                        if (e.Vtq.Quality.IsGood())
                        {
                            string itemId = e.ItemDescriptor.ItemId;
                            if (e.Vtq.Value is T && waitFor.Equals(e.Vtq.Value))
                            {
                                tcs.SetResult((T)e.Vtq.Value);
 
                            }
                            else if (e.Vtq.Value is Int16 || (Int16)e.Vtq.Value > 90)
                            {
                                if ((Int16)e.Vtq.Value == (Int16)MES.Constants.RESULTCODE.RECIPE_ERROR)
                                {
                                    tcs.SetException(new MES.Common.Exceptions.PlcErrorCodeException(MES.Constants.RESULTCODE.RECIPE_ERROR, "Unknown recipe"));
 
                                }
                                if ((Int16)e.Vtq.Value == (Int16)MES.Constants.RESULTCODE.OUT_OF_MATERIAL)
                                {
                                    tcs.SetException(new MES.Common.Exceptions.PlcErrorCodeException(MES.Constants.RESULTCODE.OUT_OF_MATERIAL, "Out of material"));
 
                                }
                            }
                        }
                        else
                        {
                            logger.DebugFormat("Quality WaitForAsync : {0}", e.Vtq.Quality.StatusBitField);
                        }
                    }
                }
                catch(Exception ex)
                {
                    logger.Fatal("OPCReader.WaitForAsync", ex);
                    throw;
                }
            };
 
            opcComponent.SubscribeItem(host, serverName, tagID, 300);
 
            return tcs.Task;
 
        }
Attachments:

Please Log in or Create an account to join the conversation.

More
19 Apr 2014 09:47 #1872 by support
Replied by support on topic Hang with Task<T>
From: O.
Sent: Friday, April 18, 2014 4:12 PM
To: Zbynek Zahradnik
Subject: Re: Problems with hang

Hi!

Yes. I think it can be delayed.

[...], and I agree with you about Dispose.

Many Thanks.

> Regards Owe

Please Log in or Create an account to join the conversation.

More
19 Apr 2014 09:29 #1871 by support
Replied by support on topic Hang with Task<T>
Dear Sir,
Originally I did not see anything wrong with your code, but later I have realized that there actually may be problems in it.

It is in the fact that
1. The UnsubscribeItem/UnsubscribeAllItems that affects an item is called from inside the item changed handler for that same item, and
2. Dispose() is called from inside an event handler on the same object that generates the event.

At this point I cannot be sure if these are the cause of the problem, but it is quite likely.
I admit that probably nowhere in the documentation we have described these limitations. They seemed kind of obvious. (for Dispose, I think this limitation would be derivable from Microsoft’s docs, because there must be no more calls on the disposed object, which cannot be assured when done this way).

At the same time, I understand what you are trying to achieve – though it may be difficult to do with the Task<T> approach.

Is there any way you can delay the call to UnsubscribeXXXX and Dispose to be performed outside the item changed handler?

If not, you can also try to remove the Dispose calls, they are not strictly necessary with our component, and they are probably a bigger problem than the UnsubscribeAllItems. With the Dispose() removed, keep the rest of your code, and see if it helps.

[...]
Best regards,

Please Log in or Create an account to join the conversation.

More
19 Apr 2014 09:27 #1870 by support
Hang with Task<T> was created by support
From: O.
Sent: Thursday, April 17, 2014 3:10 PM
To: Zbynek Zahradnik
Subject: Problems with hang

Hi

[...]

My customer needs to restart our service once or twice a day because we don't receive any ItemChanged event after subscribing,
See code in attached file.

Do you see any problems with this code?

The customer has a FestoPLC and OPC is "FestoCoDeSys.OPC".

As you see we subscribe and unsubscibe directly after receiving the awaited value. Could this be the program.

There is one other Component in the code subscribing to the same tag but not unsubscribing it.

>Ragards O.

[Subscribe.txt:]
    public Task<T> WaitForAsync<T>(string host, string serverName, string tagID, T waitFor, ILog logger) where T:struct
        {            
            TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
            EasyDAClient opcComponent = new EasyDAClient();
            opcComponent.Isolated = true;
            opcComponent.InstanceParameters.Mode.AllowAsynchronousMethod = false;
 
            opcComponent.ItemChanged += (s, e) =>
            {
                try
                {
                    if (e.Vtq != null)
                    {
                        if (e.Vtq.Quality.IsGood())
                        {
                            string itemId = e.ItemDescriptor.ItemId;
                            if (e.Vtq.Value is T && waitFor.Equals(e.Vtq.Value))
                            {
                                tcs.SetResult((T)e.Vtq.Value);
                                opcComponent.UnsubscribeAllItems();
                                opcComponent.Dispose();
                            }
                            else if (e.Vtq.Value is Int16 || (Int16)e.Vtq.Value > 90)
                            {
                                if ((Int16)e.Vtq.Value == (Int16)MES.Constants.RESULTCODE.RECIPE_ERROR)
                                {
                                    tcs.SetException(new MES.Common.Exceptions.PlcErrorCodeException(MES.Constants.RESULTCODE.RECIPE_ERROR, "Unknown recipe"));
                                    opcComponent.UnsubscribeAllItems();
                                    opcComponent.Dispose();
                                }
                                if ((Int16)e.Vtq.Value == (Int16)MES.Constants.RESULTCODE.OUT_OF_MATERIAL)
                                {
                                    tcs.SetException(new MES.Common.Exceptions.PlcErrorCodeException(MES.Constants.RESULTCODE.OUT_OF_MATERIAL, "Out of material"));
                                    opcComponent.UnsubscribeAllItems();
                                    opcComponent.Dispose();
                                }
                            }
                        }
                        else
                        {
                            logger.DebugFormat("Quality WaitForAsync : {0}", e.Vtq.Quality.StatusBitField);
                        }
                    }
                }
                catch(Exception ex)
                {
                    logger.Fatal("OPCReader.WaitForAsync", ex);
                    throw;
                }
            };            
            opcComponent.SubscribeItem(host, serverName, tagID, 300);
 
            return tcs.Task;
 
        }
 

File Attachment:

File Name: Subscribe.txt
File Size:3 KB
Attachments:

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.066 seconds