This is a migrated thread and some comments may be shown as answers.

Manage a Scope in a WF4 workflow

11 Answers 127 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
sitefinitysteve asked on 02 Jul 2010, 01:17 PM
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?

11 Answers, 1 is accepted

Sort by
0
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
answered on 05 Jul 2010, 03:57 AM
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...?
0
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
answered on 05 Jul 2010, 04:21 AM
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...


0
Jordan
Telerik team
answered on 05 Jul 2010, 07:46 AM
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
0
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
answered on 05 Jul 2010, 01:36 PM
Incidentally it throws stack overflow if you try and RETURN a OA object
0
Jordan
Telerik team
answered on 05 Jul 2010, 02:10 PM
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
0
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
answered on 05 Jul 2010, 02:12 PM
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
0
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
answered on 05 Jul 2010, 04:42 PM
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
0
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
answered on 06 Jul 2010, 12:08 AM
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?
0
Jordan
Telerik team
answered on 07 Jul 2010, 04:21 PM
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
0
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
answered on 07 Jul 2010, 04:26 PM
Yeah it makes sense...however I now have a Domain Model version of the project :)

Does this all still apply then?
0
Jordan
Telerik team
answered on 07 Jul 2010, 04:40 PM
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
Tags
General Discussions
Asked by
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
Answers by
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
Jordan
Telerik team
Share this question
or