9 Replies Latest reply on Aug 1, 2012 8:36 PM by tinklerj

    Calling PI-SDK from a C# ASP.Net Web Service

    tinklerj

      From reading some other threads in this forum, it seems that accessing PI-SDK from an MTA multi-threaded application can be very expensive for some calls (because PI-SDK is an STA object so there is cross-thread marshalling).  So the recommendation when using C# (which uses the MTA model by default) is to use the [STAThread] attribute on the main/thread entry points.

       

      However, if I am creating an ASP.Net Web service, IIS creates the threads (in a pool) and calls my Web methods inside them so I can't make the threads STA.  This may lead to poor performance when calling PI-SDK - essentially serializing all SDK calls, so I can't use parallelism or async calls to improve performance.

       

      For ASPX pages I read that you can put "AspCompat=true" in the Page directive of the markup file, which makes it use the STA threading model,but sadly an ASMX Web service only has the WebService directive which doesn't support this.

       

      <%@ WebService Language="C#" CodeBehind="MyWS.asmx.cs" Class="MyWeb.MyWS" %>

       

      Do you think the "hack" described in this article would help?  Anyone know an easier way to use PI-SDK from a web service?

       

      http://msdn.microsoft.com/en-us/magazine/cc163544.aspx

        • Re: Calling PI-SDK from a C# ASP.Net Web Service

          Jeremy,

           

          Try creating a static class that manages a pool of one or more STA threads that host the PISDK.  You can then queue the calls from IIS MTA threads asynchronously to the background threads.  The arguments should likely be translated to .NET objects in the STA threads and handed back as .NET objects to the MTA threads.

           

          If you need performance while using the PISDK, such an architecture should give good results.  (Maybe not so simple to build)

            • Re: Calling PI-SDK from a C# ASP.Net Web Service

              @Jeremy: I guess my first question would be, does it absolutely have to be PI SDK? I don't know what the requirements are for your app (i.e. what kind of calls you need to make), but there might be other PI Data Access components that would work easier in an ASP.NET, multi-threaded environment (e.g. AF SDK, PI Web Services).

               

              Maybe you can share more about your needs and requirements, and we can have this discussion.

                • Re: Calling PI-SDK from a C# ASP.Net Web Service
                  tinklerj

                  @Steve: the context is that the code all exists, uses PI-SDK, and works, albeit slowly, and I am just looking for the quickest possible way to make it more efficient.  (it basically uses ListData.ArcValue to read values at a time for multiple tags, then PIPoint.Data.UpdateValue to send results back (I wish that ListData.UpdateValue was implemented!)).

                   

                  In the longer term, yes I could look at other PI Data Access mechanisms but for my present purposes I don't have time.

                   

                  By the way, I've seen you mention in these forums something called "Rich Data Access" inthe context of AF SDK, but I have not been able to find out anything about it - what it will do, and when it will be available, are two things it would be great to know.  Oh, and will it only work using AF data references (not raw tags)?

                    • Re: Calling PI-SDK from a C# ASP.Net Web Service

                      Jeremy Tinkler

                      the context is that the code all exists, uses PI-SDK, and works, albeit slowly, and I am just looking for the quickest possible way to make it more efficient.
                          ...
                      In the longer term, yes I could look at other PI Data Access mechanisms but for my present purposes I don't have time.
                      Makes sense! Let us know if you need assistance when eventually evaluating these other PI Data Access technologies!

                       

                      Jeremy Tinkler

                      By the way, I've seen you mention in these forums something called "Rich Data Access" inthe context of AF SDK, but I have not been able to find out anything about it - what it will do, and when it will be available, are two things it would be great to know.  Oh, and will it only work using AF data references (not raw tags)?
                      I would encourage you to look at the webinar held on the topic: see "PI AF Client CTP – Rich Data Access" under the vCampus Auditorium, where all the recordings of the webinars are made available.

                       

                      As you'll hear in the webinar, there is a Community Technology Preview (CTP) version of the AF SDK with "Rich Data Access" available under the Pre-Release area of the vCampus Download Center.

                       

                      Should you need further assistance and additional details on this, please do not hesitate to post on the AF SDK Development discussion forum.

                      • Re: Calling PI-SDK from a C# ASP.Net Web Service
                        skwan

                        Jeremy Tinkler

                        By the way, I've seen you mention in these forums something called "Rich Data Access" inthe context of AF SDK, but I have not been able to find out anything about it - what it will do, and when it will be available, are two things it would be great to know.  Oh, and will it only work using AF data references (not raw tags)?

                         

                         

                        Jeremy:

                         

                        The AFSDK with RDA does allow you to directly access PI points and not just AF attributes.  The estimated release date is Q3 2012, so quite soon.  As SteveP already mentioned, please take a look at the recorded webinar in the download center.

                         

                         

                          • Re: Calling PI-SDK from a C# ASP.Net Web Service
                            tinklerj

                            I am now using PI-SDK for input in the Web service (ListData.ArcValue)and PI-API for output (piar_putarcvaluesx) - a bit like PI ACE.  Pending the arrival of RDA this is the only way I can both read and write thousands of tag values in one wire call.  It works very well and no longer suffers delays, although I expect there are inefficiencies in the cross-thread marshalling for PI-SDK.

                             

                            Another issue has arisen, however - I doubt whether anyone else has encountered this combination of circumstances (or maybe it should be a support request), but I thought I would try...

                             

                            For data reading, the call to ListData.ArcValue is inside a try/catch block.  The first thing done by the catch block is to log a message.  There is also a log message immediately before and after the call to ListData.ArcValue.

                             

                            I tried seeing what happens when the archive subsystem on the PI server (a different machine) is stopped while the Web service is active.  (The end user wants to test this for reasons that would take too long to explain).

                             

                            On my test system (Windows XP / IIS5), the ListData.ArcValue call throws an exception if the archive subsystem is down.  This is shown by the log message appearing.  The aspnet_wp.exe process keeps going.  Once piarchss has been restarted, the web service is able to handle requests again.

                             

                            On the end user's system (Windows 2008 R2 / IIS7), when the target PI server's archive subsystem is stopped, the web service worker process terminates immediately on calling ListData.ArcValue.  The exception handler does not seem to get control and no message is logged, but the w3wp.exe crash produces a Windows Application Event Log entry.

                             

                            Does anyone have any theories why the exception handler does not work in this environment?  Note that I have tried using both the DefaultAppPool (Integrated mode) and the Classic .NET AppPool (Classic mode) in IIS7 but this makes no difference.  I have also tried an Application_Error handler in global.asax.

                             

                            I am going to try and write an extremely simple Web Service that does nothing else but cause an exception (with/without calling SDK) to see what the behaviour is.  Also to try attaching the debugger to w3wp.exe in IIS7.  All this will take some time though, so I wondered if anyone had any thoughts in the meantime.

                             

                            Note that the Web service spawns a singleton STA thread to create the first PISDK.PISDKClass object.  This thread makes no SDK calls other than the object creation and just keeps going indefinitely (as recommended in the SDK help).  It is also protected by exception handlers in the event that there is some background SDK activity going on.