いまさらながらの windows workflow 入門

37
いまさらながらの Windows Workflow入門 ~そして実際にWFを実務に活用してみて思ったこと~ 株式会社アジャスト http://www.adjustgroup.co.jp

Upload: jun-ichi-sakamoto

Post on 31-May-2015

3.988 views

Category:

Education


4 download

DESCRIPTION

WF(Windows Workflow)がリリースされて数年経ちますが、今更ながら WF を実務に使ってみたところ、いい意味でいろいろ発見が。そこでもっと利用者を増やすべく社内勉強会を開催しました。これはその記録です。

TRANSCRIPT

Page 1: いまさらながらの Windows Workflow 入門

いまさらながらのWindows Workflow入門

~そして実際にWFを実務に活用してみて思ったこと~

株式会社アジャストhttp://www.adjustgroup.co.jp

Page 2: いまさらながらの Windows Workflow 入門

Agenda

• まずはコーディングして体を慣らします。

– Hands On

• なぜ、WF のシーケンシャルワークフローを使うのか?

• そのほか

– はまったこと

– ナゾ

– 参考サイト

Page 3: いまさらながらの Windows Workflow 入門

まずはコーディングして

体を慣らします。

Page 4: いまさらながらの Windows Workflow 入門

開発者の視点では "ワークフロー" って何?

• つまるところは .NET のクラス(ないしはそのインスタンス)です。

• Visual Studio のデザイナ画面でグラフィカルにデザインできますが、

究極的には、C#ソースコードを書いているに過ぎません。

Page 5: いまさらながらの Windows Workflow 入門

“アクティビティ” について

• アクティビティ(Activity) = 活動、動作

• ワークフローを構成する最小要素のこと。

• これもつまるところ、.NET クラス(ないしはそのインスタンス)のこ

とです。

• Activity クラスないしはその派生クラスになります。

• Visual Studio は大変賢く、”アクティビティ” クラスを適切にツールパ

レットに表示します。

Page 6: いまさらながらの Windows Workflow 入門

Hands On

Page 7: いまさらながらの Windows Workflow 入門

• プロジェクトの新規作成 > Visual C# > Windows > WPF アプリケーション

を作る。

• ソリューション右クリック > 新しいプロジェクトの追加 > Workflow > シー

ケンシャルワークフローライブラリ を作る。

• WpfApplication1 で、WorkflowLibrary1 への参照設定を済ませる。

• ビルドを確認。

• デザイナ画面に Delay をDropしてDurationに3秒を設定。

• デザイナ画面に CodeActivity の ExecuteCode をハンドル、参照設定で

PresentationCore と PresentationFramework を追加し、「

MessageBox.Show("OK");」をコーディング。

• ここまでやって、Workflow1.Designer.cs を開いてみる。

Page 8: いまさらながらの Windows Workflow 入門

WFを使うプログラムの構造

• WorkflowRuntime オブジェクトを new して使う。

• ワークフローの実行は WorkflowRuntime オブジェクトが司る。

• 開発した"ワークフロー"クラスは、自分で new しちゃダメ。

• WorkflowRuntime オブジェクトに、開発した"ワークフロー"の Type

を指定して、その"ワークフロー"をインスタンス化(new)してもらう。

• WorkflowRuntime オブジェクトから、new してもらったワークフロ

ーオブジェクトを内包する、WorkflowInstance オブジェクトが返さ

れるので、 その WorkflowInstance オブジェクトの Start メソッドで

、そのワークフローの実行が開始!

Page 9: いまさらながらの Windows Workflow 入門

Hands On

Page 10: いまさらながらの Windows Workflow 入門

• WpfApplication1 プロジェクトにて、

System.Workflow.Activities,ComponentModel,Runtime を参照設定追加。

• Window1.xaml のコードを表示、WorkflowRuntime の private メンバ変数

_wfRuntime を用意。

• コンストラクタ Windows1 にて WorkflowRuntime を new して

_wfRuntime に設定。

• Window1.xaml のデザイナ画面にて、Window の Unloaded イベントをハン

ドル、_wfRuntimeの StopRuntime メソッドを呼び出し。

• Window1.xaml のデザイナ画面にて、ボタンを1個配置、Clickイベントハンド

ラを作成。

• Click ハンドラ内に、CreateWorkflow 呼び出しを記述、返ってきたワークフロ

ーインスタンスに対して Start メソッド呼び出し。

• ビルドして実行。

Page 11: いまさらながらの Windows Workflow 入門

ワークフローは別スレッドで実行されます

• なので、ワークフローオブジェクトの Start メソッドは、その呼び出

しからすぐに呼び出し元に返ります。

• 同期のコーディングが必要。

• WorkflowRuntime オブジェクトから、「ワークフローの実行が完遂

したよ」などのイベントが発行されますので(※ワークフローオブジ

ェクトからではない)、予めイベントハンドラを設定しておいたりし

ます。

Page 12: いまさらながらの Windows Workflow 入門

Hands On

Page 13: いまさらながらの Windows Workflow 入門

• Window1.cs のコード表示。

• コンストラクタ Window1 () にて、_wfRuntime の WorkflowCompleted イ

ベントハンドラを追加。

• 同イベントハンドラ内で、MessageBox 呼び出しをコーディング。

Page 14: いまさらながらの Windows Workflow 入門

どうやって引数を渡すの?

• "ワークフロー" のプロパティを介在します。

• "ワークフロー" を開発するときに、受け取りたい引数は、"ワークフロ

ー" のプロパティとして実装します。

• 次にワークフローを呼び出すアプリ側では、渡したい引数を、

Dictionary<string, object> によるキーバリュー形式の辞書オブジェ

クトにまとめます。

• この辞書オブジェクトを、WorkflowRuntime オブジェクトに "ワーク

フロー" をインスタンス化(new)してもらうときに同時に、インスタン

ス化メソッドの引数に渡します。

• すると、ワークフローオブジェクトの同名のプロパティに、辞書で渡

された値が設定されて、ワークフローを開始可能となります。

Page 15: いまさらながらの Windows Workflow 入門

Hands On

Page 16: いまさらながらの Windows Workflow 入門

• Workflow1.cs のコードを表示。

• Workflow1 クラスに string Message プロパティ追加。

• codeActivity1_ExecuteCode ハンドラ中の MessageBox.Show 呼び出しにて

、この Message プロパティを表示するように改造。

• Window1.xaml のコード表示。

• button1_Click にて CreateWorkflow 呼び出しの前に、辞書構築のコードを追

加。

• CreateWorkflow の第二引数に追加。

• ビルドして実行。

Page 17: いまさらながらの Windows Workflow 入門

カスタムアクティビティ

• どうということはなく、自前で Activity クラスから派生したクラスで

す。

• Execute 仮想メソッドをオーバーライドして、そこに自由にコードを

書きます。

• ビルドしたら、Visual Studio のツールボックスに表示されるようにな

ります。

• ワークフローにDrug&Dropできます。

Page 18: いまさらながらの Windows Workflow 入門

Hands On

Page 19: いまさらながらの Windows Workflow 入門

• WorkflowLibrary1 プロジェクトにて右クリック > 追加 > アクティビティ >

Activity1.cs を追加。

• デザイナ画面がひらいちゃうけどいったん閉じる。

• Activity1.cs のコード表示。

• 派生元を SequenceActivity からただの Activity に書き換え。

• Execute メソッドのオーバーライドを追加。

• 「MessageBox.Show("OK")」を記載。

• いったんビルド。

• Workflow1.cs のデザイナ表示。

• すべてのアクティビティをいったん削除。

• ツールパレット開くと、Activity1 が表示されているので、これをDrop。

• ビルドして実行。

Page 20: いまさらながらの Windows Workflow 入門

どうやって引数を渡すの?

• カスタムアクティビティにプロパティを用意して、

これを介在します。

• しかし!

• 普通にプロパティを実装するだけではダメ。

• 「依存プロパティ(Dependency Property)」というコーディングを行

う必要があります。

• こうしておくと、デザイナ画面にて、依存プロパティのバインド先が

指定できるようになります。

• こうして依存プロパティのバインドによって、引数を受け渡していき

ます。

Page 21: いまさらながらの Windows Workflow 入門

依存プロパティのコーディング

• DependencyProperty オブジェクトで "プロパティの定義" を作成。

– プロパティの名前(string)

– プロパティの型(Type)

– どのクラスに備わっているプロパティなのか(Type)

• これを、static な public メンバ変数で公開。

• プロパティの実装コードでは、get, set それぞれに、Activityクラスの

GetValue, SetValue メソッド呼び出しを記述。

• このときに、先に用意した "プロパティの定義"、すなわち、

DependencyProperty オブジェクトを、GetValue, SetValue メソッ

ドの引数に渡す。

• ...というコードをスクラッチで書くのはありえないので、コードスニ

ペット使います。

Page 22: いまさらながらの Windows Workflow 入門

Hands On

Page 23: いまさらながらの Windows Workflow 入門

• Activity1.cs のコード表示。

• コードスニペット使う。NetFX30 から。

• string な WhatToShow 依存プロパティを実装。なお、UIPropertyMetadata

が余計なので削除。

• Exeute オーバーライドメソッド内の MessageBox 呼び出しにて、

WhatToShow 依存プロパティの値を表示するよう改訂。

• いったんビルド。

• Workflow1.cs のデザイナ表示。

• activity11 を選択すると、プロパティウィンドウに "WhatToShow" が増えて

おり、[...] が押せる。

• [...] を押すとバインドのウィンドウが表示されるので、ここで、Workflow1 ク

ラスの Message プロパティを選択する。

• ビルドして実行。

Page 24: いまさらながらの Windows Workflow 入門

依存プロパティについてもう少し...

• 受け取るだけではなく、書き換えてもよいわけです。

• 後続するアクティビティは、書き換えられたプロパティ値を使うこと

になります。

• ワークフローの"結果"、言うなれば、"戻り値" も、(ワークフローを

開始するときと同じように)プロパティ経由で受け取ります。

• WorkflowCompleted イベントの時点で、イベント引数

WorkflowCompletedEventArgs に、OutputParameters プロパティ

という辞書の形で返ってきます。

• とにかく、プロパティを媒介として処理をリレーしていくイメージで

す。

Page 25: いまさらながらの Windows Workflow 入門

Hands On

Page 26: いまさらながらの Windows Workflow 入門

• WorkflowLibrary1 プロジェクトにて右クリック > 追加 > アクティビティ >

AddBlacketActivity.cs を追加。

• デザイナ画面がひらいちゃうけどいったん閉じる。

• AddBlacketActivity.cs のコード表示。

• 派生元を SequenceActivity からただの Activity に書き換え。

• string WhatToAddBlacket な依存プロパティ追加。

• Execute メソッドのオーバーライドを追加。

• 「WhatToAddBlacket = "[" + WhatToAddBlacket + "]"」をコーディング。

• いったんビルド。

Page 27: いまさらながらの Windows Workflow 入門

• Workflow1.cs のデザイナ表示。

• ツールボックスにAddBlacketActivity が増えているので、これを activity11 の

上に Drop。

• addBlacketActivity1 を選択し、プロパティウィンドウを開き、

WhatToAddBlacket 依存プロパティのバインドを指定、Workflow1.Message

にバインド。

• ビルドして実行、メッセージが "[~]" で囲まれていることを確かめる。

Page 28: いまさらながらの Windows Workflow 入門

• Windows1.xaml のコード表示。

• _wfRuntime_WorkflowCompleted 内を

var message = e.OutputParameters["Message"] as string;

MessageBox.Show("Complete. Message is "+ message);

に書き換え。

• ビルドして実行し、ワークフロー終了後のメッセージにて、、メッセージが "[

~]" で囲まれていることを確かめる

Page 29: いまさらながらの Windows Workflow 入門

なぜ、WF のシーケンシャル

ワークフローを使うのか?

Page 30: いまさらながらの Windows Workflow 入門

一般的に言われていること

• アクティビティの組み合わせをデザイナ画面上でちょちょっと変える

だけですむので、次のようなメリットがあります。

– 仕様変更に対する耐性が高くなる

– カスタマイズ性能が向上する

• プログラマではなく、エンドユーザー自身がプログラムの動作を変更

することができるようになる可能性が開けます。

Page 31: いまさらながらの Windows Workflow 入門

実際にやってみて、それ以上に思ったこと

• "コードの可視化" というのは、並列処理化において強力であった!

• 「あ、このアクティビティとこのアクティビティは、依存関係がない

から、同時に走らせていいや」ということに気づけるようになった!

• そして、.NET 備え付けのアクティビティ=Parallel アクティビティを

組み合わせることで、デザイナ画面上で簡単に処理を並列化すること

ができる!

• さらに Replicator アクティビティを Parallel モードで使うと、配列な

どの各要素に対して繰り返しアクティビティを実行する際に、並列で

同時実行できる!

– すなわち、.NET 4.0 の Parallel.ForEach, ParallelEnumerable.AsParallel と同類

• これからのマルチコア、メニーコア時代へ向けての布石となる!

Page 32: いまさらながらの Windows Workflow 入門

Demo

Page 33: いまさらながらの Windows Workflow 入門

そのほか

Page 34: いまさらながらの Windows Workflow 入門

はまったこと

• bool な依存プロパティをバインドできない!

• プロパティウィンドウの該当プロパティの欄に、[...] がないよ?

• 実はプロパティウィンドウの、プロパティ名横のアイコンダブルクリ

ック、もしくはプロパティウィンドウ下部のタスクペインから [プロパ

ティ 'XXX' のバインド(B)...] をクリックすることでいけた。

Page 35: いまさらながらの Windows Workflow 入門

Demo

Page 36: いまさらながらの Windows Workflow 入門

ナゾ

• すでに見てきたとおり、依存プロパティのバインドを設定するウィン

ドウで、エラー言われる

• ...が、かまわず設定できるし、ちゃんと機能する。

Page 37: いまさらながらの Windows Workflow 入門

参考サイト

• Channel9のビデオ "endpoint.tv Screencast"

http://channel9.msdn.com/tags/WF+endpoint+screencasts/