工作流基础 4 - ActivityFunc的结果即使执行方法显示 true,也始终为 false
Ello,我遇到了一个自定义活动的问题,该活动执行对“ActivityFunc”的评估并返回 false,即使它在 Execute 中评估为 true。 这是我的活动
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.ComponentModel;
using System.Activities.Presentation;
namespace SomeActivities
{
///
/// Root of any number of activities used to check for a specific set of conditions to be true (Trigger Conditions)
///
public sealed class Trigger : NativeActivity, IActivityTemplateFactory
{
///
/// The initial Condition that determines if the trigger should be scheduled
///
/// The condition.
[RequiredArgument]
public ActivityFunc <bool> Condition { get; set; }
///
/// The resulting action that is scheduled if the Condition is true
///
/// The child.
[RequiredArgument]
public ActivityAction Child { get; set; }
///
/// Gets or sets the value holding whether or not the trigger matches the condition
///
/// The type of the match.
public MatchType MatchType{ get; set; }
private CompletionCallback<bool> OnExecutionCompleteCallBack;
protected override void Execute(NativeActivityContext context)
{
this.OnExecutionCompleteCallBack = this.OnConditionComplete;
context.ScheduleFunc<bool>(this.Condition, this.OnExecutionCompleteCallBack);
}
public void OnConditionComplete(NativeActivityContext context, ActivityInstance instance, bool result)
{
if (instance.State == ActivityInstanceState.Canceled)
{
context.Abort();
return;
}
//check if Condition evaluation returns true
//Always show as false
if (result)
{
//If so then schedule child Activity
context.ScheduleAction(Child);
}
}
Activity IActivityTemplateFactory.Create(System.Windows.DependencyObject target)
{
return new Trigger()
{
Child = new ActivityAction()
{
DisplayName = "Trigger Child Action"
},
Condition = new ActivityFunc<bool>()
{
DisplayName = "Trigger Conditionals",
Result = new DelegateOutArgument<bool>()
},
DisplayName = "Trigger",
MatchType = MatchType.Matches,
};
}
}
}
因此,当在 Execute 方法中评估我的条件时,即使我将条件的结果打印为 true,它也会调用 OnConditionComplete 并返回结果(这始终为 false)。那么这里有什么我看不到的明显错误吗?
更新
好吧,我认为 Marice 谈论的是在类中拥有回调,并且只是让 OnConditionComplete 方法指向回调。我确实改变了这一点,但没有看到改变。如果我能以某种方式从 ActivityFunc
更新 2
问题显然来自 ActivityFunc
。我将不得不仔细检查并检查该条件可能存在哪些问题。不确定这是否应该涉及一个新问题,因为它在技术上尚未解决,但我会考虑将一个测试条件放在一起,如果没有其他东西显示我所处的位置。
好的,这是我用作子活动的一个简单示例,即使它在执行中评估为 true,它也始终返回 false
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Activities.Presentation;
using System.ComponentModel;
using System.Drawing;
namespace SomeActivities
{
public sealed class DataHandlerTypeName : NativeActivity,IActivityTemplateFactory
{
// Define an activity input argument of type string
[RequiredArgument]
public InArgument ImportContext { get; set; }
///
/// Gets or sets the handler type name to check.
///
/// The handler type name to check.
[RequiredArgument]
public string HandlerTypeNameToCheck { get; set; }
///
/// Performs the trigger check for the matching Data Type Handler Names
///
/// The context.
protected override void Execute(NativeActivityContext context)
{
var ic = this.ImportContext.Get(context);
if (1==1)
{
//context.SetValue(base.Result, true);
Result.Set(context, true);
}
else
{
//context.SetValue(base.Result, true);
Result.Set(context, false);
}
}
#region IActivityTemplateFactory Members
Activity IActivityTemplateFactory.Create(System.Windows.DependencyObject target)
{
return new DataHandlerTypeName()
{
ImportContext = this.ImportContext,
HandlerTypeNameToCheck = "Default"
};
}
#endregion
}
}
Ello, I'm having an issue with a custom activity that preforms an evaluation of a `ActivityFunc ` and returns false even though it is evaluated in Execute to be true.
Here is my activity
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.ComponentModel;
using System.Activities.Presentation;
namespace SomeActivities
{
///
/// Root of any number of activities used to check for a specific set of conditions to be true (Trigger Conditions)
///
public sealed class Trigger : NativeActivity, IActivityTemplateFactory
{
///
/// The initial Condition that determines if the trigger should be scheduled
///
/// The condition.
[RequiredArgument]
public ActivityFunc <bool> Condition { get; set; }
///
/// The resulting action that is scheduled if the Condition is true
///
/// The child.
[RequiredArgument]
public ActivityAction Child { get; set; }
///
/// Gets or sets the value holding whether or not the trigger matches the condition
///
/// The type of the match.
public MatchType MatchType{ get; set; }
private CompletionCallback<bool> OnExecutionCompleteCallBack;
protected override void Execute(NativeActivityContext context)
{
this.OnExecutionCompleteCallBack = this.OnConditionComplete;
context.ScheduleFunc<bool>(this.Condition, this.OnExecutionCompleteCallBack);
}
public void OnConditionComplete(NativeActivityContext context, ActivityInstance instance, bool result)
{
if (instance.State == ActivityInstanceState.Canceled)
{
context.Abort();
return;
}
//check if Condition evaluation returns true
//Always show as false
if (result)
{
//If so then schedule child Activity
context.ScheduleAction(Child);
}
}
Activity IActivityTemplateFactory.Create(System.Windows.DependencyObject target)
{
return new Trigger()
{
Child = new ActivityAction()
{
DisplayName = "Trigger Child Action"
},
Condition = new ActivityFunc<bool>()
{
DisplayName = "Trigger Conditionals",
Result = new DelegateOutArgument<bool>()
},
DisplayName = "Trigger",
MatchType = MatchType.Matches,
};
}
}
}
So when my condition is evaluated in the Execute Method it calls OnConditionComplete with the result (which is what is always false) even though if I print the result of the condition to be true. So is there something obviously wrong here that I don't see?
Update
Okay I think Marice talking about having the callback in the class and just having the OnConditionComplete method point to the callback. I did change that but haven't seen a change. If I could somehow retrieve the value from the ActivityFunc<bool> child
condition when its actually executing or save its value afterward, that would work great. I've played around with CacheMetadata's metadata to see if there was anything that I could find that would allow me to do so but haven't found anything as of yet.
Update 2
The problem apparently is coming from the ActivityFunc <bool> Condition
. I'm going to have to go through and check what the issue(s) with the Condition might be. Not sure if this should go to a new question or not since its technically not solved but I'll see about putting together a test Condition to go off of and if nothing else show where I'm at.
Update 3
Okay this is a bare bones example of what I use as a child activity that always returns false even though it evaluates to true in the execution
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Activities.Presentation;
using System.ComponentModel;
using System.Drawing;
namespace SomeActivities
{
public sealed class DataHandlerTypeName : NativeActivity,IActivityTemplateFactory
{
// Define an activity input argument of type string
[RequiredArgument]
public InArgument ImportContext { get; set; }
///
/// Gets or sets the handler type name to check.
///
/// The handler type name to check.
[RequiredArgument]
public string HandlerTypeNameToCheck { get; set; }
///
/// Performs the trigger check for the matching Data Type Handler Names
///
/// The context.
protected override void Execute(NativeActivityContext context)
{
var ic = this.ImportContext.Get(context);
if (1==1)
{
//context.SetValue(base.Result, true);
Result.Set(context, true);
}
else
{
//context.SetValue(base.Result, true);
Result.Set(context, false);
}
}
#region IActivityTemplateFactory Members
Activity IActivityTemplateFactory.Create(System.Windows.DependencyObject target)
{
return new DataHandlerTypeName()
{
ImportContext = this.ImportContext,
HandlerTypeNameToCheck = "Default"
};
}
#endregion
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你好,我以前从未见过,只是碰巧分享了我的 IP。
你做错了什么。在其他地方,就是这样。
要么包含您正在使用的活动的 DLL 不是最新的,要么工作流定义已经过时并且不包含您认为它具有的功能。或者它是完全不同的东西。
我已经剥离了您的代码并将其压缩到一个示例项目中。喜欢在这里看到它:
这是简单的条件:
简单,不是吗?这是评估此条件的主机,如果返回 true,则运行单个子活动。请注意,我正在 Create 方法中构建活动,因此不必创建编辑器。
将这两个放在工作流控制台应用程序中,并将 AnTriggerHost 放在工作流上。设置几个断点并观察它的飞行。这是工作流程 xaml:
您的问题不在于活动,而在于您如何使用它们。您假设您的测试设备是正确的,但事实并非如此。
供将来参考...当我遇到这种情况时,原因是我在 IActivityTemplateFactory 的 Create 方法中设置了
Result
这会导致工作流定义中的结果集,从而破坏了 ActivityFunc 模式。
Hello someone who I have never met before and just happens to share my IP.
You're doing something wrong. Elsewhere, that is.
Either the DLL with the activities you're using isn't fresh, or the workflow definition is out of date and doesn't hold what you believe it does. Or its something completely different.
I've stripped down your code and compressed it into a sample project. Like to see it here we go:
This is the simple condition:
Simple, no? Here's the host that evaluates this condition and, if it returns true, runs a single child activity. Note, I'm constructing the activity in the Create method so I don't have to create an editor.
Drop these two in a Workflow Console app and drop the AnTriggerHost on the workflow. Set ye a couple breakpoints and watch it fly. Here's the workflow xaml:
Your issue doesn't lie in the activities, it lies in how you're using them. You're assuming your test rig is correct when it isn't.
For future reference... When this happens to me, the cause is that I set
Result
within the Create method of the IActivityTemplateFactoryThis results in the result set within the workflow definition, which breaks the ActivityFunc pattern.
ScheduleFunc 始终采用 ActivityFunc,其中您的条件定义为 ActivityFunc。不确定非通用 ActivityFunc 来自哪里。另外,CompletionCallback 应该是一个 CompletionCallback。
更新:
我使用的测试代码:
和 IActivityTemplateFactory.Create:
ScheduleFunc always takes a ActivityFunc where your condition is defined as ActivityFunc. Not sure where the non generic ActivityFunc comes from. Also the CompletionCallback should be a CompletionCallback.
Update:
The test code I used:
And the IActivityTemplateFactory.Create: