locked
Workflow (WF4) Debugger Not Stopping at Breakpoints RRS feed

  • Question

  • I'm getting the following error when invoking Run() on a WorkflowApplication that'd been loaded from a XAML file via ActivityXamlServices.Load. Please note this is NOT preventing the execution of the WF, just the ability for WF breakpoints to be hit.

     

    Workflow : Instrumentation for debugger fails. Reason: 'Cannot create unknown type '{clr-namespace:ScreeningInterview;assembly=System.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35}FreedomScreenOutActivity'.' Line number '86' and line position '38'..

     

    The WorkFlowApplication is instantiated as follows:

     

    var rulesAssembly = Assembly.Load(rulesAssemblyName); // namespace=ScreeningInterview; assembly=ScreeningInterviewRules.dll

    var reader = new XamlXmlReader(fileName, new XamlXmlReaderSettings() { LocalAssembly = rulesAssembly, ProvideLineInfo = true });

    workflowApplication = new WorkflowApplication(ActivityXamlServices.Load(reader), new Dictionary<string, object>() { { "App", this as IWorkflowIntegration } });

     

    Rules Assembly contains the XAML represented by "filename" and LocalAssembly is needed given the use of various types (e.g. enums) and custom WF Activities contained within it; including the custom FreedomScreenOutActivity refereced in the instrumentation error.

     

    Thinking if might be something with the FreedomScreenOutActivity itself, i removed it from the WF to no avail. It simply identified another reference to a local type. The extract below illustrate the Activity references and line of XAML making use of the activities/types:

     

    xmlns:local="clr-namespace:ScreeningInterview" xmlns:local1="clr-namespace:ScreeningInterview.Types"

    <local:FreedomScreenOutActivity App="[App]" sap:VirtualizedContainerService.HintSize="200,22" NextScreen="[NextScreen]" VAComplete="[VAComplete]" />

    OutArgument x:TypeArguments="local1:ScreeningResult">[Result]</OutArgument

     

    I'd like to be able to debug the WF given its relative complexity... Therefore any guidance would be greatly appreciated!!!

     

    If any additional information or details are necessary please do not hesitate to ask. Thanks!


    • Edited by RosaKnowza Sunday, October 2, 2011 12:25 AM test
    Sunday, October 2, 2011 12:17 AM

Answers

  • var rulesAssembly = Assembly.Load(rulesAssemblyName); // namespace=ScreeningInterview; assembly=ScreeningInterviewRules.dll

    var reader = new XamlXmlReader(fileName, new XamlXmlReaderSettings() { LocalAssembly = rulesAssembly, ProvideLineInfo = true });

    workflowApplication = new WorkflowApplication(ActivityXamlServices.Load(reader), new Dictionary<string, object>() { { "App", this as IWorkflowIntegration } });

     

     

    xmlns:local="clr-namespace:ScreeningInterview" xmlns:local1="clr-namespace:ScreeningInterview.Types"

    <local:FreedomScreenOutActivity App="[App]" sap:VirtualizedContainerService.HintSize="200,22" NextScreen="[NextScreen]" VAComplete="[VAComplete]" />

    OutArgument x:TypeArguments="local1:ScreeningResult">[Result]</OutArgument

    Hi Rosa,
    As I read the post it sounds like maybe there is something a little non-standard in the way you are doing things. Let's start by assuming you have a FreedomScreenOutActivity in the RulesAssembly.

    The next point I can observe is that you are using FreedomScreenOutActivity in a XAML file, I'll call it Foo.xaml.

    There are 3 groups of scenarios for Foo.xaml in terms of how local assembly matters.

    Scenario 1) it is compiled into a type in an assembly: BarAssembly
    Scenario 2) it is just a 'loose' Foo.xaml file, and not compiled with XamlBuildTask as part of a project.
    Scenario 3) Foo.xaml is part of RulesAssembly, and is compiled into a type there.

    Given the scenarios, this is what I expect:

    In scenario 1) it is not expected that you use XAML Local Assembly to reference FreedomScreenOutActivity (you would use LocalAssembly to reference activities from BarAssembly). It is also not expected that you would use XamlServices.Load() to instantiate the workflow. Instead it is expected that you would use new Foo().

    In scenario 2) it is not expected that you use XAML Local Assembly at all. You should always see full assembly references in the XAML. Obviously you can't use new Foo(), you should use ActivityXamlServices.Load() assuming your XAML is an <Activity x:Class> XAML. And XamlServices.Load() should works for cases where your XAML is not x:Class but has a root such as <Sequence>.

    In senario 3) this is the only scenario where you should use XAML Local Assembly to refer to FreedomScreenOutActivity. Also, in this scenario, you should be using 'new Foo()' to load your activity.

    From your sample code I you are scenario 1 or 3. Does this make sense, and using the recommended loading techniques do you encounter any problems?

    Tim

    • Proposed as answer by Tim Lovell-Smith Sunday, October 2, 2011 5:08 PM
    • Marked as answer by LeoTang Monday, October 10, 2011 1:12 AM
    Sunday, October 2, 2011 3:41 AM

All replies

  • I've had this happen before.  A couple things to try:

    1.  If you have your workflow in source control, make sure it's checked out and writable.

    2.  Make a small change to your workflow (like move an activity around) and save and rebuild.  This will force the workflow to rebuild the XAMLX and get everything back in sync.

    Although I saw your updated post just now, and it may not be this simple.


    Tom Overton
    • Edited by Tom_Overton Sunday, October 2, 2011 12:29 AM
    Sunday, October 2, 2011 12:27 AM
  • Thanks for the quick reply Tom!

     

    Prior to posting this, I too was running down that angle by ensuring the "sad:XamlDebuggerXmlReader.FileName" was referencing the correct file (and it was). I've been making changes along. I believe this started when I began utilizing the "local:" activities and types contained within the "ScreeningInterviewRules" assembly.

    • Edited by RosaKnowza Sunday, October 2, 2011 12:36 AM mistype
    Sunday, October 2, 2011 12:34 AM
  • Thinking about this some more.... I wondered why is the FreedomScreenOutActivity is not being resolved appropriatly (at least from the debugger instrumentation perspective) as indicated by the Visual Studio Output Window:

    Workflow : Instrumentation for debugger fails. Reason: 'Cannot create unknown type '{clr-namespace:ScreeningInterview;assembly=System.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35}FreedomScreenOutActivity'.' Line number '86' and line position '38'..

    A point of interest is the fact the the namespace=ScreeningInterview[correct!] yet the assembly=System.Activities [should be ScreeningInterviewRules, after all, that's where is lives].

    So with that, I went back and simply "forced" the XAML'sxmlns:local and xmlns:local1 to include the assembly qualifier as opposed to repling upon the XamlXmlReaderSettings.LocalAssembly to create the association:

    xmlns:local="clr-namespace:ScreeningInterview;assembly=ScreeningInterviewRules" xmlns:local1="clr-namespace:ScreeningInterview.Types;assembly=ScreeningInterviewRules"

    And...

    var reader = new XamlXmlReader(fileName /*, new XamlXmlReaderSettings() { LocalAssembly = rulesAssembly, ProvideLineInfo = true }*/)

    What do you know... it just worked!

     

    I when back and verified the rulesAssembly that I was previously using to set the LocalAssembly property and it appears to be correct (from the VS2010 debugger):

     

    {ScreeningInterviewRules, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null}

    What might be wrong with my usage of the XamlXmlReaderSetting.LocalAssembly that would?:

    1.  Allow the WF to run (i.e. resolve all necessary type)

    2.  Yet, generate the output errors above which prevent WF debugging

    Note: The WF will not execute with LocalAssembly not set and the xmlns:local / xmlns:local1 not containing the fully-qualified assembly, so I know the LocalAssembly has some good effect (e.g. not forcing me to manually change the XAML to resolve local types) :-)

    Sunday, October 2, 2011 2:09 AM
  • var rulesAssembly = Assembly.Load(rulesAssemblyName); // namespace=ScreeningInterview; assembly=ScreeningInterviewRules.dll

    var reader = new XamlXmlReader(fileName, new XamlXmlReaderSettings() { LocalAssembly = rulesAssembly, ProvideLineInfo = true });

    workflowApplication = new WorkflowApplication(ActivityXamlServices.Load(reader), new Dictionary<string, object>() { { "App", this as IWorkflowIntegration } });

     

     

    xmlns:local="clr-namespace:ScreeningInterview" xmlns:local1="clr-namespace:ScreeningInterview.Types"

    <local:FreedomScreenOutActivity App="[App]" sap:VirtualizedContainerService.HintSize="200,22" NextScreen="[NextScreen]" VAComplete="[VAComplete]" />

    OutArgument x:TypeArguments="local1:ScreeningResult">[Result]</OutArgument

    Hi Rosa,
    As I read the post it sounds like maybe there is something a little non-standard in the way you are doing things. Let's start by assuming you have a FreedomScreenOutActivity in the RulesAssembly.

    The next point I can observe is that you are using FreedomScreenOutActivity in a XAML file, I'll call it Foo.xaml.

    There are 3 groups of scenarios for Foo.xaml in terms of how local assembly matters.

    Scenario 1) it is compiled into a type in an assembly: BarAssembly
    Scenario 2) it is just a 'loose' Foo.xaml file, and not compiled with XamlBuildTask as part of a project.
    Scenario 3) Foo.xaml is part of RulesAssembly, and is compiled into a type there.

    Given the scenarios, this is what I expect:

    In scenario 1) it is not expected that you use XAML Local Assembly to reference FreedomScreenOutActivity (you would use LocalAssembly to reference activities from BarAssembly). It is also not expected that you would use XamlServices.Load() to instantiate the workflow. Instead it is expected that you would use new Foo().

    In scenario 2) it is not expected that you use XAML Local Assembly at all. You should always see full assembly references in the XAML. Obviously you can't use new Foo(), you should use ActivityXamlServices.Load() assuming your XAML is an <Activity x:Class> XAML. And XamlServices.Load() should works for cases where your XAML is not x:Class but has a root such as <Sequence>.

    In senario 3) this is the only scenario where you should use XAML Local Assembly to refer to FreedomScreenOutActivity. Also, in this scenario, you should be using 'new Foo()' to load your activity.

    From your sample code I you are scenario 1 or 3. Does this make sense, and using the recommended loading techniques do you encounter any problems?

    Tim

    • Proposed as answer by Tim Lovell-Smith Sunday, October 2, 2011 5:08 PM
    • Marked as answer by LeoTang Monday, October 10, 2011 1:12 AM
    Sunday, October 2, 2011 3:41 AM
  • Hi Tim,

    Thank you for your informative response... I'd say that my usage scenario mostly resembles scenario #2. That is, my intent in that the XAML is "loose" (although i did not do anything specific to make it such) in that a generic framework is loading/executing the specified XAML WF file.

    What I've Done:

    Looked at Scenario #2 Closer

    Since I want loose XAML (i think ;-)), I modified the XAML propertied to have "None" as the build action and removed x:Class. Upon doing so I noticed that the *.g.cs files were not being generated (as you'd expect). I also forced the XAML to be regenerated via the designer (Ctrl-s) yet the local, assembly-less xmlns references remain. This subsequently requires LocalAssembly, which then produces the Instrumentation error's illustrated above. And yes, prevents breakpoints being hit!

    I think the local references remain since the loose XAML file happens to be part of the same project as Activities/types being referenced by the loose XAML.

    Implemented Scenario #3

    As per your suggestion, I modified the implemetation to reflect scenario #3 above. With that, I was able to get the breakpoints hit and I simply instanced my root activity by specifying an AssemblyQualifiedName for Activity's name as follows:

    String rootName = “ScreeningInterview.ScreeningRules, ScreeningInterviewRules, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”

    Type rootActivity = Type.GetType(rootName);

     

    WorkflowApplication = newWorkflowApplication(Activator.CreateInstance(rootActivity)as Activity,new Dictionary<string, object>() { { "App", this as IWorkflowIntegration} });

     

    The root activity is named "Screening Rules" and it is being complied into the assembly "ScreeningInterviewRules" via the XamlBuildTask.

     

    Sunday, October 2, 2011 4:50 PM
  • I think the local references remain since the loose XAML file happens to be part of the same project as Activities/types being referenced by the loose XAML.

    Yes, that is correct - To avoid generating local XAML namespaces, the XAML file should not be part of the same project as the Activiites/types that you are referencing.

    Tim
    Sunday, October 2, 2011 5:08 PM