我的Workflow书签选择触发器出了什么问题?

时间:2010-06-30 19:37:24

标签: c# workflow .net-4.0 workflow-foundation-4 workflow-activity

我有一个NativeActivity派生的活动,我写的是使用书签作为挑选分支的触发器。使用我在MSDN上找到的东西,我试着写这个来触发分支。该分支包含通过发送活动向远程客户端激活服务回调的活动。如果我为触发器设置了延迟,则回调会成功触发客户端。如果我使用我的代码活动,则挑选分支活动不会触发。

public sealed class UpdateListener : NativeActivity<ClientUpdate>
{
    [RequiredArgument]
    public InArgument<string>     BookmarkName { get; set; }

    protected override void Execute(NativeActivityContext context)
    {
        context.CreateBookmark(BookmarkName.Get(context),
                    new BookmarkCallback(this.OnResumeBookmark));
    }


    protected override bool CanInduceIdle
    {
        get { return true; }
    }


    public void OnResumeBookmark(NativeActivityContext context, Bookmark bookmark, object obj )
    {
        Result.Set(context, (ClientUpdate)obj);
    }
}

因此,需要arg为未来的书签引用设置书签名称以执行触发器。 OnResumeBoookmark()接受由我的托管workflowapp的应用程序传递的ClientUpdate对象。活动是返回对象,以便ClientUpdate可以传递给工作流,并通过pick分支中的send活动将其发送到远程客户端。理论上无论如何。

出于某种原因,这似乎是正确的,但感觉不对。我不确定我是否应该以不同的方式编写活动以照顾我的WF服务所需的内容。

2 个答案:

答案 0 :(得分:1)

如果您创建了一个扩展(实现IWorkflowInstanceExtension)来执行此操作,我认为您的意图会更清晰。

例如:

public sealed class AsyncWorkExtension 
    : IWorkflowInstanceExtension
{
    // only one extension per workflow
    private WorkflowInstanceProxy _proxy;
    private Bookmark _lastBookmark;

    /// <summary>
    /// Request the extension does some work for an activity
    /// during which the activity will idle the workflow
    /// </summary>
    /// <param name="toResumeMe"></param>
    public void DoWork(Bookmark toResumeMe)
    {
        _lastBookmark = toResumeMe;
        // imagine I kick off some async op here
        // when complete system calls WorkCompleted below
        // NOTE:  you CANNOT block here or you block the WF!
    }

    /// <summary>
    /// Called by the system when long-running work is complete
    /// </summary>
    /// <param name="result"></param>
    internal void WorkCompleted(object result)
    {
        //NOT good practice!  example only
        //this leaks resources search APM for details
        _proxy.BeginResumeBookmark(_lastBookmark, result, null, null);
    }

    /// <summary>
    /// When implemented, returns any additional extensions 
    /// the implementing class requires.
    /// </summary>
    /// <returns>
    /// A collection of additional workflow extensions.
    /// </returns>
    IEnumerable<object> IWorkflowInstanceExtension
        .GetAdditionalExtensions()
    {
        return new object[0];
    }

    /// <summary>
    /// Sets the specified target 
    /// <see cref="WorkflowInstanceProxy"/>.
    /// </summary>
    /// <param name="instance">The target workflow instance to set.</param>
    void IWorkflowInstanceExtension
        .SetInstance(WorkflowInstanceProxy instance)
    {
        _proxy = instance;
    }
}

在活动中,您可以这样使用:

 var ext = context.GetExtension<AsyncWorkExtension>();
 var bookmark = context.CreateBookmark(BookmarkCallback);
 ext.DoWork(bookmark);
 return;

这种方式更加明确(而不是使用书签名称来向“外部”世界传达意义),并且如果您需要发送比书签名称更多的信息,则更容易扩展。

答案 1 :(得分:0)

这里有没有真正恢复书签的东西?如果不是,工作流程将非常耐心地等待,不会发生任何事情。