以前 Parallel アクティビティ等のいかにも非同期っぽく動きそうなアクティビティは実のところそうは動かない、という記事を書きました。実際に何故非同期で動作しないかというと、Parallel アクティビティ等の内部に設定するアクティビティが非同期で動作しないから、というのが本当の理由になります。
つまるところ非同期で動作するアクティビティを準備さえすれば、Parallel 等のアクティビティでも非同期に動作させることが可能となります。
まずフォーム上で適当な文字を入力させるようなアクティビティとして AsyncInputDialogActivity というように作成します。それを用いてこのような Workflow を作成した場合、動作としては Branch1 アクティビティ内部に設定してある AsyncInputDialogActivity の処理が完了しなければ Branch2 の動作に移行しないように思われます。しかし AsyncInputDialog アクティビティを非同期で動作するようにした場合は、Branch1 、Branch2 の AsyncInputDialog アクティビティが同時に動作し、同時に入力待ち状態になります。
実際のロジックは次のようになります。
1: Imports System.Activities2:3: Public Class AsyncInputDialogActivity4: Inherits AsyncCodeActivity5:6: Public Property InputStrings As OutArgument(Of String)7: Private Delegate Function AsyncInputDialogDelegate() As String8:9: Protected Overrides Function BeginExecute(ByVal context As System.Activities.AsyncCodeActivityContext, ByVal callback As System.AsyncCallback, ByVal state As Object) As System.IAsyncResult10: Dim asyncInputDialogDel = New AsyncInputDialogDelegate(AddressOf DisplayInputDialog)11: context.UserState = asyncInputDialogDel12: Return asyncInputDialogDel.BeginInvoke(callback, state)13: End Function14:15: Protected Overrides Sub EndExecute(ByVal context As System.Activities.AsyncCodeActivityContext, ByVal result As System.IAsyncResult)16: Dim asyncInputDialogDel = TryCast(context.UserState, AsyncInputDialogDelegate)17: Dim resultStrings = asyncInputDialogDel.EndInvoke(result)18: InputStrings.Set(context, resultStrings)19: End Sub20:21: Private Function DisplayInputDialog() As String22: Dim result As String = ""23: Using dlg As New UsingActivityForm24: If dlg.ShowDialog = Windows.Forms.DialogResult.OK Then25: result = dlg.InputString26: End If27: End Using28: Return result29: End Function30:31: End Class
このように、AsyncCodeActivity を継承し実装を行うと非同期で動作するアクティビティを作成する事ができます。内部的に ShowDialog を利用していても問題ありません。先程の Workflow を実行すると、入力用フォームが二つ起動されます。
実際に Workflow を利用する上では必須となる非同期アクティビティ。作成するとしても思っている以上に簡単にできるのが見えたのではないでしょうか。
0 件のコメント:
コメントを投稿