Manage a Scope in a WF4 workflow

Thread is closed for posting
12 posts, 0 answers
  1. Steve
    Steve avatar
    1888 posts
    Member since:
    Dec 2008

    Posted 02 Jul 2010 Link to this post

    How do you recommend handling of a IObjectScope in a WF4 instance (not persisted)

    Do I make the scope at the start of the flow and pass it around with args (pain in the balls), or a Helper method perhaps?

    ...do I create the scope initially, then keep calling ObjectScopeProvider1.ObjectScope in my coded steps?
  2. Steve
    Steve avatar
    1888 posts
    Member since:
    Dec 2008

    Posted 04 Jul 2010 Link to this post

    Ok, so I've tried making an activity called GetScope which returns an IObjectScope and stores it in a variable

    However if I try and USE that scope to retrieve an object I crash...making a Dispose activity (accepting a scope InArg) works though...?
  3. Steve
    Steve avatar
    1888 posts
    Member since:
    Dec 2008

    Posted 04 Jul 2010 Link to this post

    Ok, I think I have it working....properly?

    So I made a helper class
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Activities; 
    using Telerik.OpenAccess; 
     
    namespace RTOWorkflowService.Scope { 
        public class RTOScope { 
            public static IObjectScope Scope{ 
                get
                    IObjectScope scope = RTOWorkflowObjectScopeProvider.ObjectScope(); 
                    if (scope == null
                        scope = RTOWorkflowObjectScopeProvider.GetNewObjectScope(); 
     
                    return scope; 
                } 
            } 
        } 
     


    My Coded Activities call it
            protected override void Execute(CodeActivityContext context) { 
                IObjectScope scope = RTOWorkflowService.Scope.RTOScope.Scope; 


    Then at the end of the workflow, I call use my Dispose Activity
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Activities; 
    using Telerik.OpenAccess; 
     
    namespace RTOWorkflowService.Scope { 
     
        public sealed class DisposeScope : CodeActivity { 
            protected override void Execute(CodeActivityContext context) { 
                IObjectScope scope = RTOWorkflowObjectScopeProvider.ObjectScope(); 
                if(scope != null
                    scope.Dispose(); 
            } 
        } 
     

    Does that seem okay?...seems to RUN fine anyway...


  4. Jordan
    Admin
    Jordan avatar
    547 posts

    Posted 05 Jul 2010 Link to this post

    Hi Steve,

    As soon as you dispose the scope at the end of your workflow this should work fine.
    Also, keeping the scope alive during execution of the workflow is a good idea if you want to pass persistent classes between activities.

    Kind regards,
    Jordan
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  5. Steve
    Steve avatar
    1888 posts
    Member since:
    Dec 2008

    Posted 05 Jul 2010 Link to this post

    Incidentally it throws stack overflow if you try and RETURN a OA object
  6. Jordan
    Admin
    Jordan avatar
    547 posts

    Posted 05 Jul 2010 Link to this post

    Hi Steve,

    In order to help you  we will need the following:
    1. the full exception including exception message and stack trace
    2. a simple project that we can use to reproduce the issue will best,
    if for some reason you cannot send us such a project we will at least need enough information (and code) in order to reproduce your exact scenario

    Looking forward to your reply.

    Sincerely yours,
    Jordan
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  7. Steve
    Steve avatar
    1888 posts
    Member since:
    Dec 2008

    Posted 05 Jul 2010 Link to this post

    Okay, I don't think it's doable anyway since the object would be returned from a WCF contract object, and not be attached to a scope?...

    I'll try and put together a quick sample
  8. Steve
    Steve avatar
    1888 posts
    Member since:
    Dec 2008

    Posted 05 Jul 2010 Link to this post

    Ok, so my method above fails...

     IObjectScope scope = RTOWorkflowObjectScopeProvider.ObjectScope();  
                    if (scope == null)  
                        scope = RTOWorkflowObjectScopeProvider.GetNewObjectScope();  
      
                    return scope;  

    This completes, but the first time I try to use it (well...second call actually)

    I get a scope closed exception

    ...and this fun one

    Server Error in '/' Application.

    Error executing query: Telerik.OpenAccess.RT.sql.SQLException: A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The handle is invalid.)
      at Telerik.OpenAccess.RT.Adonet2Generic.Impl.PreparedStatementImp.executeQuery()
      at OpenAccessRuntime.Relational.conn.PooledPreparedStatement.executeQuery()
      at OpenAccessRuntime.Relational.fetch.FetchResultImp.execute()
    SQL:
    SELECT  TOP(??T) a.[ProgramID] AS COL1, a.[DefaultAdmin] AS COL2, a.[Created] AS COL3, a.[DefaultAdmin] AS COL4, a.[DefaultChainID] AS COL5, a.[Enabled] AS COL6, a.[Message] AS COL7, a.[NotifyOnApproval] AS COL8, a.[ParentID] AS COL9, a.[ParentID] AS COL10, a.[ProgramName] AS COL11 FROM [RTO_Programs] a WHERE a.[ProgramID] = ?          Telerik.OpenAccess.RT.sql.SQLException: A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The handle is invalid.)
      at Telerik.OpenAccess.RT.Adonet2Generic.Impl.PreparedStatementImp.executeQuery()
      at OpenAccessRuntime.Relational.conn.PooledPreparedStatement.executeQuery()
      at OpenAccessRuntime.Relational.fetch.FetchResultImp.execute()

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.ServiceModel.FaultException`1[[System.ServiceModel.ExceptionDetail, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]: Error executing query: Telerik.OpenAccess.RT.sql.SQLException: A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The handle is invalid.)
      at Telerik.OpenAccess.RT.Adonet2Generic.Impl.PreparedStatementImp.executeQuery()
      at OpenAccessRuntime.Relational.conn.PooledPreparedStatement.executeQuery()
      at OpenAccessRuntime.Relational.fetch.FetchResultImp.execute()
    SQL:
    SELECT  TOP(??T) a.[ProgramID] AS COL1, a.[DefaultAdmin] AS COL2, a.[Created] AS COL3, a.[DefaultAdmin] AS COL4, a.[DefaultChainID] AS COL5, a.[Enabled] AS COL6, a.[Message] AS COL7, a.[NotifyOnApproval] AS COL8, a.[ParentID] AS COL9, a.[ParentID] AS COL10, a.[ProgramName] AS COL11 FROM [RTO_Programs] a WHERE a.[ProgramID] = ?          Telerik.OpenAccess.RT.sql.SQLException: A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The handle is invalid.)
      at Telerik.OpenAccess.RT.Adonet2Generic.Impl.PreparedStatementImp.executeQuery()
      at OpenAccessRuntime.Relational.conn.PooledPreparedStatement.executeQuery()
      at OpenAccessRuntime.Relational.fetch.FetchResultImp.execute()

    Source Error:

    Line 384:        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
    Line 385:        RTO.Service.NewRequest.GetDataResponse RTO.Service.NewRequest.IService.GetData(RTO.Service.NewRequest.GetDataRequest request) {
    Line 386:            return base.Channel.GetData(request);
    Line 387:        }
    Line 388:        

    Source File: c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\08e0e17f\aee487ed\App_WebReferences.l_swkpxj.0.cs    Line: 386

    Stack Trace:

    [FaultException`1: Error executing query: Telerik.OpenAccess.RT.sql.SQLException: A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The handle is invalid.)
       at Telerik.OpenAccess.RT.Adonet2Generic.Impl.PreparedStatementImp.executeQuery()
       at OpenAccessRuntime.Relational.conn.PooledPreparedStatement.executeQuery()
       at OpenAccessRuntime.Relational.fetch.FetchResultImp.execute()
    SQL:
    SELECT  TOP(??T) a.[ProgramID] AS COL1, a.[DefaultAdmin] AS COL2, a.[Created] AS COL3, a.[DefaultAdmin] AS COL4, a.[DefaultChainID] AS COL5, a.[Enabled] AS COL6, a.[Message] AS COL7, a.[NotifyOnApproval] AS COL8, a.[ParentID] AS COL9, a.[ParentID] AS COL10, a.[ProgramName] AS COL11 FROM [RTO_Programs] a WHERE a.[ProgramID] = ?          Telerik.OpenAccess.RT.sql.SQLException: A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The handle is invalid.)
       at Telerik.OpenAccess.RT.Adonet2Generic.Impl.PreparedStatementImp.executeQuery()
       at OpenAccessRuntime.Relational.conn.PooledPreparedStatement.executeQuery()
       at OpenAccessRuntime.Relational.fetch.FetchResultImp.execute()]
       System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +4767763
       System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +1725
       RTO.Service.NewRequest.IService.GetData(GetDataRequest request) +0
       RTO.Service.NewRequest.ServiceClient.RTO.Service.NewRequest.IService.GetData(GetDataRequest request) in c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\08e0e17f\aee487ed\App_WebReferences.l_swkpxj.0.cs:386
       RTO.Service.NewRequest.ServiceClient.GetData(NewRequestContract NewRequestContract) in c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\08e0e17f\aee487ed\App_WebReferences.l_swkpxj.0.cs:392
       NewRequestForm.get_ServiceDataResponse() in d:\websites\ca\medportal\postgrad\Apps\RTO\NewRequestForm.aspx.cs:109
       NewRequestForm.InsertDetailLabelText() in d:\websites\ca\medportal\postgrad\Apps\RTO\NewRequestForm.aspx.cs:553
       NewRequestForm.Page_PreRender(Object sender, EventArgs e) in d:\websites\ca\medportal\postgrad\Apps\RTO\NewRequestForm.aspx.cs:502
       System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +25
       System.EventHandler.Invoke(Object sender, EventArgs e) +0
       System.Web.UI.Control.PreRenderRecursiveInternal() +113
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4185
    


    Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1
  9. Steve
    Steve avatar
    1888 posts
    Member since:
    Dec 2008

    Posted 05 Jul 2010 Link to this post

    Got frustrated by the above error

    Re-generated the entire thing with the new Domain Model method and moved over all the partial classes

    No more error...but can you tell me how to handle the entity context?...still needs a dispose?
  10. Jordan
    Admin
    Jordan avatar
    547 posts

    Posted 07 Jul 2010 Link to this post

    Hello Steve,

    I liked your approach with the Dispose activity, and I think that it should actually work.

    You just need to change it a little:
    1. do not use the ScopeProvider.ObjectScope method because this will not reset the scope after you dispose it and will return a disposed scope every time after the first (I think this explains the disposed scope exception)
    2. implement your own scope management (which you already did to some extent) based on the ScopeProvider.GetNewObjectScope method
    3. after you dispose the scope, set the scope variable to null so that a new scope is returned next time instead of the disposed one

    I hope this helps.

    Regards,
    Jordan
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  11. Steve
    Steve avatar
    1888 posts
    Member since:
    Dec 2008

    Posted 07 Jul 2010 Link to this post

    Yeah it makes sense...however I now have a Domain Model version of the project :)

    Does this all still apply then?
  12. Jordan
    Admin
    Jordan avatar
    547 posts

    Posted 07 Jul 2010 Link to this post

    Hello Steve,

    With the domain model approach it will be the same basically, but instead of an object scope you have a context and to create a new context instance you will use the constructor instead of some static method.

    All the best,
    Jordan
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Back to Top