1

我编写了一个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() 接收一个ClientUpdate由我的应用程序传递的对象,该应用程序托管工作流应用程序。该活动将返回对象,以便ClientUpdate可以将其传递给工作流并通过pick分支中的发送活动将其发送到远程客户端。反正理论上。

出于某种原因,它似乎是正确的,但感觉是错误的。我不确定是否应该以不同的方式编写 Activity 来处理我的 WF 服务所需的内容。

4

2 回答 2

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;

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

于 2010-07-22T16:37:30.747 回答
0

真的有什么东西在这里恢复了书签吗?如果不是,工作流程将非常耐心地等待,什么都不会发生。

于 2010-07-01T19:44:29.910 回答