共用方式為


使用命令式程式碼撰寫工作流程

本主題僅適用於 Windows Workflow Foundation 4。

工作流程定義是配置之活動物件的樹狀結構。有很多方式可定義這個活動的樹狀結構,包含手動編輯 XAML 或使用工作流程設計工具來產生 XAML。不過,XAML 並非必要條件。您也可以程式設計的方式建立工作流程定義。本主題會提供使用程式碼建立工作流程定義的概觀。

建立工作流程定義

具現化活動型別的執行個體,並設定活動物件的屬性,即可建立工作流程定義。對於不包含任何子活動的活動,這個部分僅需使用幾行程式碼便能完成。

Activity wf = new WriteLine
{
    Text = "Hello World."
};

WorkflowInvoker.Invoke(wf);
Ee358749.note(zh-tw,VS.100).gif注意:
本主題中的範例使用 WorkflowInvoker 來執行簡易的工作流程。如需詳細資訊叫用工作流程、傳遞引數以及可用的不同裝載選項的詳細資訊,請參閱使用 WorkflowInvoker 與 WorkflowApplication

在這個範例中,會建立由單一 WriteLine 活動構成的工作流程。WriteLine 活動的 Text 引數會進行設定,並叫用工作流程。如果活動包含子活動,則建構方式會相當類似。下列範例會使用包含兩個 WriteLine 活動的 Sequence 活動。

Activity wf = new Sequence
{
    Activities =
    {
        new WriteLine
        {
            Text = "Hello"
        },
        new WriteLine
        {
            Text = "World."
        }
    }
};

WorkflowInvoker.Invoke(wf);

使用物件初始設定式

本主題的範例會使用物件初始化語法。物件初始化語法在使用程式碼建立工作流程定義時會很有用,因為它會在工作流程中提供活動的階層式檢視,並顯示活動之間的關係。當您以程式設計方式來建立工作流程時,不一定非得使用物件初始化語法。下列範例在功能上等同於先前的範例。

WriteLine hello = new WriteLine();
hello.Text = "Hello";

WriteLine world = new WriteLine();
world.Text = "World";

Sequence wf = new Sequence();
wf.Activities.Add(hello);
wf.Activities.Add(world);

WorkflowInvoker.Invoke(wf);

如需詳細資訊物件初始設定式的詳細資訊,請參閱 HOW TO:初始化物件但不呼叫建構函式 (C# 程式設計手冊)HOW TO:使用物件初始設定式宣告物件

處理變數、常值和運算式

使用程式碼建立工作流程定義時,請注意哪個程式碼是做為建立工作流程定義的一部分,以及哪個程式碼是做為該工作流程執行個體的一部分執行。例如,下列工作流程目的是要產生隨機號碼,並將它寫入主控台。

Variable<int> n = new Variable<int>
{
    Name = "n"
};

Activity wf = new Sequence
{
    Variables = { n },
    Activities =
    {
        new Assign<int>
        {
            To = n,
            Value = new Random().Next(1, 101)
        },
        new WriteLine
        {
            Text = new InArgument<string>((env) => "The number is " + n.Get(env))
        }
    }
};

當執行此工作流程定義程式碼時,會呼叫 Random.Next,且會將結果儲存於工作流程定義做為常值。此工作流程的許多執行個體都可加以叫用,且所有的執行個體都會顯示相同的號碼。若要在工作流程執行期間產生隨機號碼,必須使用每當工作流程執行時所計算的運算式。

new Assign<int>
{
    To = n,
    Value = new VisualBasicValue<int>("New Random().Next(1, 101)")
}

VisualBasicValue 是以 Visual Basic 語法表示的運算式,可用來當做運算式中的右值 (r-value),且每當執行內含的活動時會進行計算。運算式的結果會指派至工作流程變數 n,且會由工作流程中的下一個活動使用這些結果。若要在執行階段時存取工作流程變數 n 的值,必須要有 ActivityContext。這可以使用下列 Lambda 運算式來進行存取。

new WriteLine
{
    Text = new InArgument<string>((env) => "The number is " + n.Get(env))
}

Lambda 運算式不可序列化為 XAML 格式。若要讓此運算式相容於 XAML,請使用 ExpressionServicesConvert,如下列範例所示。

new WriteLine
{
    //Text = new InArgument<string>((env) => "The number is " + n.Get(env))
    Text = ExpressionServices.Convert((env) => "The number is " + n.Get(env))
}

也可以使用 VisualBasicValue

new WriteLine
{
    //Text = new InArgument<string>((env) => "The number is " + n.Get(env))
    //Text = ExpressionServices.Convert((env) => "The number is " + n.Get(env))
    Text = new VisualBasicValue<string>("\"The number is \" + n.ToString()")
}

如需詳細資訊如需運算式的詳細資訊,請參閱運算式

引數與動態活動

工作流程定義是在程式碼中藉由組裝活動至活動樹狀目錄,並設定任何屬性與引數所建立。可繫結現有的引數,但無法新增新引數至活動。這包含傳遞至根活動的工作流程引數。在命令式程式碼中,會將工作流程引數指定為新 CLR 型別的屬性,並且在 XAML 中使用 x:Classx:Member 來宣告它們。因為將工作流程定義建立為記憶體內物件的樹狀結構時,並未建立任何新 CLR 型別,所以無法新增引數。但是,可新增引數至 DynamicActivity。在此範例中會建立 DynamicActivity,它採用兩個整數引數並將其同時加入,然後傳回結果。不僅會針對每個引數建立 DynamicActivityProperty,且會將作業的結果指派至 DynamicActivityResult 引數。

InArgument<int> Operand1 = new InArgument<int>();
InArgument<int> Operand2 = new InArgument<int>();

DynamicActivity<int> wf = new DynamicActivity<int>
{
    Properties =
    {
        new DynamicActivityProperty
        {
            Name = "Operand1",
            Type = typeof(InArgument<int>),
            Value = Operand1
        },
        new DynamicActivityProperty
        {
            Name = "Operand2",
            Type = typeof(InArgument<int>),
            Value = Operand2
        }
    },

    Implementation = () => new Sequence
    {
        Activities = 
        {
            new Assign<int>
            {
                To = new ArgumentReference<int> { ArgumentName = "Result" },
                Value = new InArgument<int>((env) => Operand1.Get(env) + Operand2.Get(env))
            }
        }
    }
};

Dictionary<string, object> wfParams = new Dictionary<string, object>
{
    { "Operand1", 25 },
    { "Operand2", 15 }
};

int result = WorkflowInvoker.Invoke(wf, wfParams);
Console.WriteLine(result);

如需詳細資訊如需動態活動的詳細資訊,請參閱使用 DynamicActivity 在執行階段建立活動