1

Windowsワークフローを機能させようとしていますが、少し困惑しています。

単一のワークフローが機能するようになりましたが、今はもう少し複雑なことをしようとしています。ワークフローを開始します。各アクティビティ自体にワークフローが含まれています。(メインプログラムが「入力、ロジック、および出力」のアクティビティを開始し、それぞれに「ユーザーのプロンプト、入力の取得など」などの追加のアクティビティがあるようなものを想像してください)

メインプログラムからアクティビティにパラメータを渡していないときは、ここ(http://msdn.microsoft.com/en-us/magazine/gg535667.aspx )の例を使用して、正常に動作しています。私の質問は、「Variables」と「metadata.SetVariablesCollection」がNativeActivityでどのように正確に機能するか、および低レベルのアクティビティのパラメーターを取得する方法です。

これは私が現在試していることです:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Collections.ObjectModel;
using System.Activities.Statements;

namespace Project1
{
    internal class MainProgram
    {
        internal static void Main(string[] args)
        {
            try
            {
                var act = new SimpleSequence();

                act.Activities.Add((Activity)(new WriteSomeText()));
                act.Activities.Add((Activity)(new WriteSomeText()));
                act.Activities.Add((Activity)(new WriteSomeText()));

                act.Variables.Add(new Variable<string> ("stringArg", "TEXT"));

                WorkflowInvoker.Invoke(act);
            }
            catch (Exception ex)
            {
                System.Console.WriteLine("EXCEPTION: {0}", ex);
            }
        }

        public class WriteSomeText : CodeActivity
        {
            [RequiredArgument]
            public InArgument<string> stringArg { get; set; }

            protected override void Execute(CodeActivityContext context)
            {
                string output = context.GetValue(stringArg);
                System.Console.WriteLine(output);
            }

        }

        public class SimpleSequence : NativeActivity
        {
            Collection<Activity> activities;
            Collection<Variable> variables;

            Variable<int> current = new Variable<int> { Default = 0 };

            public Collection<Activity> Activities
            {
                get
                {
                    if (this.activities == null)
                        this.activities = new Collection<Activity>();

                    return this.activities;
                }
                set
                {
                    this.activities = value;
                }
            }

            public Collection<Variable> Variables
            {
                get
                {
                    if (this.variables == null)
                        this.variables = new Collection<Variable>();

                    return this.variables;
                }
                set
                {
                    this.variables = value;
                }
            }

            protected override void CacheMetadata(NativeActivityMetadata metadata)
            {
                metadata.SetChildrenCollection(this.activities);
                metadata.SetVariablesCollection(this.variables);
                metadata.AddImplementationVariable(this.current);
            }

            protected override void Execute(NativeActivityContext context)
            {
                if (this.Activities.Count > 0)
                    context.ScheduleActivity(this.Activities[0], onChildComplete);
            }

            void onChildComplete(NativeActivityContext context, ActivityInstance completed)
            {
                int currentExecutingActivity = this.current.Get(context);
                int next = currentExecutingActivity + 1;

                if (next < this.Activities.Count)
                {
                    context.ScheduleActivity(this.Activities[next], this.onChildComplete);

                    this.current.Set(context, next);
                }
            }
        }
    }
}

これにより、次の例外がスローされます。

EXCEPTION: System.Activities.InvalidWorkflowException: The following errors were encountered while processing the workflow tree:
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
   at System.Activities.Validation.ActivityValidationServices.ThrowIfViolationsExist(IList`1 validationErrors)
   at System.Activities.Hosting.WorkflowInstance.ValidateWorkflow(WorkflowInstanceExtensionManager extensionManager)
   at System.Activities.Hosting.WorkflowInstance.RegisterExtensionManager(WorkflowInstanceExtensionManager extensionManager)
   at System.Activities.WorkflowApplication.EnsureInitialized()
   at System.Activities.WorkflowApplication.RunInstance(WorkflowApplication instance)
   at System.Activities.WorkflowApplication.Invoke(Activity activity, IDictionary`2 inputs, WorkflowInstanceExtensionManager extensions, TimeSpan timeout)
   at System.Activities.WorkflowInvoker.Invoke(Activity workflow, TimeSpan timeout, WorkflowInstanceExtensionManager extensions)
   at System.Activities.WorkflowInvoker.Invoke(Activity workflow)
   at Project1.MainProgram.Main(String[] args) in c:\users\user\documents\visual studio 2010\Projects\ModelingProject1\Project1\MainProgram.cs:line 25

私は1つのパラメーターしか渡さないことを知っていますが、例外は3つのパラメーターが欠落していることを示しています。私はこれを適切に行う方法について何かが欠けています。

4

1 に答える 1

2

stringArgをInArgumentとして正しく宣言していますが、 SimpleSequence内で呼び出すときに値を渡していません。

次のように、すべてのアクティビティ自体を構築しながら、コンストラクタを使用して何かを渡すことができます。

public class WriteSomeText : CodeActivity
{
    [RequiredArgument]
    public InArgument<string> stringArg { get; set; }

    public WriteSomeText(string stringArg)
    {
        this.stringArg = stringArg;
    }

    protected override void Execute(CodeActivityContext context
    {
        string output = context.GetValue(stringArg);
        System.Console.WriteLine(output);
    }
}

// Calling the activity like this:

internal static void Main(string[] args)
{
    var act = new SimpleSequence()
    {
        Activities =
        {
            new WriteSomeText("hello"),
            new WriteSomeText("world"),
            new WriteSomeText("!")
        }
    };

    WorkflowInvoker.Invoke(act);

    Console.WriteLine("Press any key to exit");
    Console.ReadKey();
}

また、コンストラクターを使用してコレクションを初期化するのがベスト プラクティスであることにも注意してください。

public SimpleSequence()
{
    activities = new Collection<Activity>();
    variables = new Collection<Variable>();
}

この方法は、アクティビティを初期化するのにさらに直感的です。

var act = new SimpleSequence()
{
    Activities =
    {
        new WriteSomeText("hello"),
        new WriteSomeText("world"),
        new WriteSomeText("!")
    },
    Variables =
    {
        new Variable<int>("myNewIntVar", 10),
        // ....
    }
};

編集:

この問題に対処するには、他にもいくつかの方法があります。これは、WF4 の世界を始めるときの親友です。

WF\Basic\CustomActivities\Code-Bodiedをチェックして、この特定のケースを少しプッシュしてください。

于 2011-09-06T17:59:40.060 に答える