2011年4月11日月曜日

非同期アクティビティ

以前 Parallel アクティビティ等のいかにも非同期っぽく動きそうなアクティビティは実のところそうは動かない、という記事を書きました。実際に何故非同期で動作しないかというと、Parallel アクティビティ等の内部に設定するアクティビティが非同期で動作しないから、というのが本当の理由になります。

つまるところ非同期で動作するアクティビティを準備さえすれば、Parallel 等のアクティビティでも非同期に動作させることが可能となります。

WF4-1

まずフォーム上で適当な文字を入力させるようなアクティビティとして AsyncInputDialogActivity というように作成します。それを用いてこのような Workflow を作成した場合、動作としては Branch1 アクティビティ内部に設定してある AsyncInputDialogActivity の処理が完了しなければ Branch2 の動作に移行しないように思われます。しかし AsyncInputDialog アクティビティを非同期で動作するようにした場合は、Branch1 、Branch2 の AsyncInputDialog アクティビティが同時に動作し、同時に入力待ち状態になります。

実際のロジックは次のようになります。

  1: Imports System.Activities
  2: 
  3: Public Class AsyncInputDialogActivity
  4:     Inherits AsyncCodeActivity
  5: 
  6:     Public Property InputStrings As OutArgument(Of String)
  7:     Private Delegate Function AsyncInputDialogDelegate() As String
  8: 
  9:     Protected Overrides Function BeginExecute(ByVal context As System.Activities.AsyncCodeActivityContext, ByVal callback As System.AsyncCallback, ByVal state As Object) As System.IAsyncResult
 10:         Dim asyncInputDialogDel = New AsyncInputDialogDelegate(AddressOf DisplayInputDialog)
 11:         context.UserState = asyncInputDialogDel
 12:         Return asyncInputDialogDel.BeginInvoke(callback, state)
 13:     End Function
 14: 
 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 Sub
 20: 
 21:     Private Function DisplayInputDialog() As String
 22:         Dim result As String = ""
 23:         Using dlg As New UsingActivityForm
 24:             If dlg.ShowDialog = Windows.Forms.DialogResult.OK Then
 25:                 result = dlg.InputString
 26:             End If
 27:         End Using
 28:         Return result
 29:     End Function
 30: 
 31: End Class


このように、AsyncCodeActivity を継承し実装を行うと非同期で動作するアクティビティを作成する事ができます。内部的に ShowDialog を利用していても問題ありません。先程の Workflow を実行すると、入力用フォームが二つ起動されます。



実際に Workflow を利用する上では必須となる非同期アクティビティ。作成するとしても思っている以上に簡単にできるのが見えたのではないでしょうか。

0 件のコメント:

コメントを投稿