我的工作流程书签选择触发器做错了什么?

发布于 2024-09-08 02:33:18 字数 1066 浏览 10 评论 0原文

我编写了一个 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 分支中的发送活动将其发送到远程客户端。无论如何理论上。

出于某种原因,它似乎是正确的,但感觉是错误的。我不确定是否应该以不同的方式编写活动来满足 WF 服务的需要。

I have a NativeActivity derived activity that I wrote that is to use bookmarks as a trigger for a pick branch. Using something I found on MSDN I tried writing this to trigger the branch. The branch contains activities that fire service callbacks to remote clients via send activities. If I set a delay for the trigger, callbacks fire to the clients successfully. If I use my code activity, the pick branch activities don't fire.

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);
    }
}

So it takes an arg to set the bookmark name for future bookmark references to execute the trigger. OnResumeBoookmark() takes in a ClientUpdate object that is passed by my application that is hosting the workflowapp. The activity is to return the object so the ClientUpdate can be passed to the workflow and have it sent to the remote clients via the send activity in the pick branch. In theory anyways.

For some reason it seems to be correct but feels wrong. I'm not sure if I should write the Activity in a different way to take care of what I need for my WF service.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别挽留 2024-09-15 02:33:19

我认为如果您创建一个扩展(实现 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;

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

I think your intentions would be a bit clearer if you created an extension (that implements IWorkflowInstanceExtension) to perform your action here.

For example:

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;
    }
}

Within the Activity, you'd use this thusly:

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

This way is much more explicit (instead of using the bookmark name to convey meaning to the "outside" world) and is much easier to extend if, say, you require to send out more information than a bookmark name.

晨光如昨 2024-09-15 02:33:19

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

Is there something actually resuming the bookmark here? If not the workflow will wait very patiently and nothing will happen.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文