WF 4 Rehosted Designer - 获取 foreach InArgument 值 [英] WF 4 Rehosted Designer - get foreach InArgument Value

查看:25
本文介绍了WF 4 Rehosted Designer - 获取 foreach InArgument 值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读本文后:

所以基本上在您的断点所在的位置,您可以访问变量值,因为这些值是在您的活动范围内定义为变量"的.然而,'item' 变量实际上只能从父循环活动中访问.因此,您必须获取当前执行活动的模型项,然后向上遍历树以找到包含所需 DelegateInArgument 的父项.

你能具体说明你想要实现的目标吗?当您在重新托管的设计器中调试工作流时,您是否希望在用户界面中更改时向用户显示变量值?

编辑 - 添加了跟踪示例

因此,如果您希望在工作流程执行期间显示变量值,我们需要使用跟踪来实现这一点.在示例中,您使用作者已经实现了一些基本的跟踪.因此,要实现您想要的扩展变量跟踪,您需要更改跟踪配置文件.

首先修改 WorkflowDesignerHost.xaml.cs 文件,修改 RunWorkflow 方法,定义 SimulatorTrackingParticipant 如下.

 SimulatorTrackingParticipant simTracker = new SimulatorTrackingParticipant(){TrackingProfile = 新的 TrackingProfile(){Name = "CustomTrackingProfile",查询 ={新的 CustomTrackingQuery(){名称 = 所有,活动名称 = 全部},new WorkflowInstanceQuery(){**州 = {所有 },**},新的 ActivityStateQuery(){//订阅所有状态的所有活动的跟踪记录活动名称 = 所有,状态 = { 所有 },**参数 = {all},**//提取工作流变量和参数作为活动跟踪记录的一部分//VariableName = "*" 允许提取作用域内的所有变量//活动的变量 ={{ 全部 }}}}}};

这现在将正确捕获所有工作流实例状态,而不仅仅是开始/完成.您还将捕获记录跟踪数据的每个活动的所有参数,而不仅仅是变量.这很重要,因为感兴趣的变量"实际上(如前所述)是一个 DelegateInArgument.

因此,一旦我们更改了跟踪配置文件,我们还需要更改 SimulatorTrackingParticipant.cs 以提取我们现在正在跟踪的其他数据.

如果您更改 OnTrackingRecordReceived 方法以包含以下部分,这些将在执行期间捕获变量数据和参数数据.

 protected void OnTrackingRecordReceived(TrackingRecord record, TimeSpan timeout){System.Diagnostics.Debug.WriteLine(String.Format("收到的跟踪记录:{0} 超时:{1} 秒.", record, timeout.TotalSeconds));if (TrackingRecordReceived != null){ActivityStateRecord activityStateRecord = 记录为ActivityStateRecord;如果(活动状态记录!= null){IDictionary<字符串,对象>变量 = activityStateRecord.Variables;StringBuilder vars = new StringBuilder();if (variables.Count > 0){vars.AppendLine("\n\tVariables:");foreach (KeyValuePair variable in variables){vars.AppendLine(String.Format("\t\tName: {0} Value: {1}", variable.Key, variable.Value));}}}如果(活动状态记录!= null){IDictionary<字符串,对象>参数 = activityStateRecord.Arguments;StringBuilder args = new StringBuilder();if (arguments.Count > 0){args.AppendLine("\n\tArgument:");foreach (KeyValuePair 参数中的参数){args.AppendLine(String.Format("\t\tName: {0} Value: {1}", argument.Key, argument.Value));}}//将参数冒泡到用户界面供用户查看!}if((activityStateRecord != null) && (!activityStateRecord.Activity.TypeName.Contains("System.Activities.Expressions"))){if (ActivityIdToWorkflowElementMap.ContainsKey(activityStateRecord.Activity.Id)){TrackingRecordReceived(this, new TrackingEventArgs(记录,暂停,ActivityIdToWorkflowElementMap[activityStateRecord.Activity.Id]));}}别的{TrackingRecordReceived(this, new TrackingEventArgs(record, timeout,null));}}}

希望这会有所帮助!

After reading this article:

http://blogs.msdn.com/b/tilovell/archive/2009/12/29/the-trouble-with-system-activities-foreach-and-parallelforeach.aspx

I have defined the ForEachFactory as follows:

public class ForEachFactory<T> : IActivityTemplateFactory
{
    public Activity Create(DependencyObject target)
    {
        return new ForEach<T>
        {
            DisplayName = "ForEachFromFactory",
            Body = new ActivityAction<T>
            {
                Argument = new DelegateInArgument<T>("item")
            }
        };
    }
}

All works well but is it possible to check how that DelegeateInArgument in my case named "item" changes its value ? So if i have defined an array in the variables section and initialized with {1, 2, 3} i need a way to check how the "item" takes value 1, 2 and then 3.

To be more accurate, i've added this pic, with a breakpoint on the WriteLine activity inside the foreach. When the execution will stop there, is there a way to find out what the value of item is ?

EDIT 1:

Possible solution in my case: After struggling a bit more i found one interesting thing:

Adding one of my custom activities in the Body of the ForEach, i am able to get the value of the item like this :

So, my activity derives from : CodeActivity

Inside the protected override String[] Execute(CodeActivityContext context) i am doing this job.To be honest, this solves the thing somehow, but it is doable only in my custom activities. If i would put a WriteLine there for example, i would not be able to retrieve that value.

解决方案

you can access the DelegeateInArgument of a ForEach activity by inspecting the ModelItem trees parent and checking for DelegeateInArgument's. If you need a specific code example to achieve this I may need a some time to code the example. As it has been a long time since I did this, see my question i asked over on msdn

So basically where your break point is, you can access the variable values as these are defined with n the scope of your activity as 'variables'. However the 'item' variable is actually only accessible from the parent loop activity. So you have to get the model item of the current executing activity and then traverse up the tree to find the parent containing the desired DelegateInArgument.

Can you flesh out exactly what you want to achieve? Is it that when your debugging the workflow in the re-hosted designer you want to display the variable values to the user as they change in the UI?

Edit - added tracking example

So as your wanting to display the variable values during execution of the workflow we need to use tracking to achieve this. In the example your using the author has already implemented some basic tracking. So to achieve the extended variable tracking you want you will need to alter the tracking profile.

Firstly amend the WorkflowDesignerHost.xaml.cs file alter the RunWorkflow method to define the SimulatorTrackingParticipant as below.

            SimulatorTrackingParticipant simTracker = new SimulatorTrackingParticipant()
            {
                TrackingProfile = new TrackingProfile()
                {
                    Name = "CustomTrackingProfile",
                    Queries = 
                    {
                        new CustomTrackingQuery() 
                        {
                            Name = all,
                            ActivityName = all
                        },
                        new WorkflowInstanceQuery()
                        {
                            **States = {all },**
                        },
                        new ActivityStateQuery()
                        {
                            // Subscribe for track records from all activities for all states
                            ActivityName = all,
                            States = { all },
                            **Arguments = {all},**
                            // Extract workflow variables and arguments as a part of the activity tracking record
                            // VariableName = "*" allows for extraction of all variables in the scope
                            // of the activity
                            Variables = 
                            {                                
                                { all }   
                            }
                        }   
                    }
                }
            };

This will now correctly capture all workflow instance states rather than just Started/Completed. You will also capture all Arguments on each activity that records tracking data rather than just the variables. This is important because the 'variable' were interested in is actually (as discussed earlier) a DelegateInArgument.

So once we have changed the tracking profile we also need to change the SimulatorTrackingParticipant.cs to extract the additional data we are now tracking.

If you change the OnTrackingRecordReceived method to include the following sections these will capture variable data and also Argument data during execution.

    protected void OnTrackingRecordReceived(TrackingRecord record, TimeSpan timeout)
    {
        System.Diagnostics.Debug.WriteLine(
            String.Format("Tracking Record Received: {0} with timeout: {1} seconds.", record, timeout.TotalSeconds)
        );

        if (TrackingRecordReceived != null)
        {
            ActivityStateRecord activityStateRecord = record as ActivityStateRecord;

            if (activityStateRecord != null)
            {
                IDictionary<string, object> variables = activityStateRecord.Variables;
                StringBuilder vars = new StringBuilder();

                if (variables.Count > 0)
                {
                    vars.AppendLine("\n\tVariables:");
                    foreach (KeyValuePair<string, object> variable in variables)
                    {
                        vars.AppendLine(String.Format(
                        "\t\tName: {0} Value: {1}", variable.Key, variable.Value));
                    }
                }

            }

            if (activityStateRecord != null)
            {
                IDictionary<string, object> arguments = activityStateRecord.Arguments;
                StringBuilder args = new StringBuilder();

                if (arguments.Count > 0)
                {
                    args.AppendLine("\n\tArgument:");
                    foreach (KeyValuePair<string, object> argument in arguments)
                    {
                        args.AppendLine(String.Format(
                        "\t\tName: {0} Value: {1}", argument.Key, argument.Value));
                    }
                }

                //bubble up the args to the UI for the user to see!
            }


            if((activityStateRecord != null) && (!activityStateRecord.Activity.TypeName.Contains("System.Activities.Expressions")))
            {
                if (ActivityIdToWorkflowElementMap.ContainsKey(activityStateRecord.Activity.Id))
                {
                    TrackingRecordReceived(this, new TrackingEventArgs(
                                                    record,
                                                    timeout,
                                                    ActivityIdToWorkflowElementMap[activityStateRecord.Activity.Id]
                                                    )

                        );
                }

            }
            else
            {
                TrackingRecordReceived(this, new TrackingEventArgs(record, timeout,null));
            }

        }

    }

Hope this helps!

这篇关于WF 4 Rehosted Designer - 获取 foreach InArgument 值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆