活動 Pick 可簡化一組事件觸發程式的模型化,後面接著其對應的處理程式。 Pick 活動包含一組 PickBranch 活動,其中每個 PickBranch 是 Trigger 活動與 Action 活動之間的配對。 在運行時間,會平行執行所有分支的觸發程式。 當一個觸發程式完成時,就會執行其對應的動作,並取消所有其他觸發程式。 .NET Framework 4.6.1Pick 活動的行為類似於 .NET Framework 3.5 ListenActivity 活動。
下列來自 使用 Pick 活動 SDK 範例的螢幕截圖顯示 Pick 活動具有兩個分支。 一個分支具有稱為 「讀取輸入」的觸發程式,這是從命令行讀取輸入的自定義活動。 第二個分支具有 Delay 活動觸發器。 如果 讀取輸入 活動在 Delay 活動完成之前收到數據,則會取消 Delay 延遲,並將問候寫入主控台。 否則,如果 讀取輸入 活動未在配置的時間內接收數據,則會取消,並將逾時訊息寫入主控台。 這是用來將超時添加至任何動作的常見模式。
最佳做法
使用 Pick 時,執行的分支是其觸發條件最先完成的分支。 就概念上來說,所有觸發器會以平行方式執行,其中一個觸發器可能會在因另一個觸發器完成而被取消前,先執行其大部分邏輯。 考慮到這一點,使用 Pick 活動時要遵循的一般指導方針是將觸發程式視為代表單一事件,並將盡可能少的邏輯放入其中。 理想情況下,觸發器應該包含足夠的邏輯來接收事件,而該事件的所有處理過程應該交由分支的動作來完成。 這個方法會將觸發程式執行之間的重疊量降到最低。 例如,假設 Pick 有兩個觸發程式,其中每個觸發程式都包含一個 Receive 活動,後面接著其他邏輯。 如果額外的邏輯引進了閑置點,則兩 Receive 個活動都有可能順利完成。 一個觸發程式將會完全完成,而另一個觸發程式則會部分完成。 在某些情況下,接受訊息,然後部分完成處理是不可接受的。 因此,當使用 WF 內建傳訊活動,例如 Receive 和 SendReply 時,通常會將 Receive 用於觸發程式,而 SendReply 和其他邏輯則應盡可能放入動作中。
在設計師工具中使用挑選活動
若要在設計工具中使用 Pick,請在工具箱中尋找 Pick 和 PickBranch 。 將 [挑選] 拖放到畫布上。 根據預設,設計工具中的新 挑選 活動會包含兩個分支。 若要新增其他分支,請拖曳 PickBranch 活動,並將它放在現有分支旁邊。 活動可以放入到任意 PickBranch 的 Trigger 區域或 Action 區域的 挑選活動中。
在程式代碼中使用 Pick 活動
活動 Pick 是藉由填入其 Branches 集合中的 PickBranch 活動來使用。 活動 PickBranch 每一個都有一個類型為 Trigger 的 Activity 屬性。 當指定的活動完成執行後,Action 會執行。
下列程式碼範例示範如何使用 Pick 活動來為從主控台讀取行的活動設置逾時。
Sequence body = new Sequence()
{
Variables = { name },
Activities =
{
new System.Activities.Statements.Pick
{
Branches =
{
new PickBranch
{
Trigger = new ReadLine
{
Result = name,
BookmarkName = "name"
},
Action = new WriteLine
{
Text = ExpressionServices.Convert<string>(ctx => "Hello " +
name.Get(ctx))
}
},
new PickBranch
{
Trigger = new Delay
{
Duration = new TimeSpan(0, 0, 5)
},
Action = new WriteLine
{
Text = "Time is up."
}
}
}
}
}
};
<Sequence xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Sequence.Variables>
<Variable x:TypeArguments="x:String" Name="username" />
</Sequence.Variables>
<Pick>
<PickBranch>
<PickBranch.Trigger>
<ReadLine BookmarkName="name" Result="username" />
</PickBranch.Trigger>
<WriteLine>[String.Concat("Hello ", username)]</WriteLine>
</PickBranch>
<PickBranch>
<PickBranch.Trigger>
<Delay>00:00:05</Delay>
</PickBranch.Trigger>
<WriteLine>Time is up.</WriteLine>
</PickBranch>
</Pick>
</Sequence>