SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Vista時代のプログラミングモデル .NET Framework 3.0入門

WF(Windows Workflow Foundation)チュートリアル 後編

Vista時代のプログラミングモデル .NET Framework 3.0入門 (7)

  • X ポスト
  • このエントリーをはてなブックマークに追加

WF(Windows Workflow Foundation)は.NET Framework 3.0に搭載された新しいワークフロー基盤です。後編では、WFの提供するワークフローの永続化サービスについて解説し、.NET Framework 3.0の新機能に関するシリーズの締めくくりとします。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 WFチュートリアル 前編中編ではWFの概要、シーケンシャルワークフロー、ステートマシンワークフローについて解説しました。最終回となる今回は、WFの提供するワークフローの永続化サービスについて解説します。

対象読者

 本記事はC#でのプログラミングを行ったことがある方を対象としています。

 サンプルを動作させるための環境設定等は『WPF(Windows Presentation Foundation)+XAML入門 前編』をご覧ください。

SQL Serverへのワークフロー永続化

 中編で解説したとおり、ステートマシンワークフローを使うアプリケーションでは、複数のワークフローが同時に実行、あるいはイベント待ちをすることになります。サンプルのように数個のワークフローであれば、同時にメモリ上に存在しても問題ありませんが、ワークフローの数が多くなってくると、メモリを圧迫してくるようになるかもしれません。

 しかも大抵のケースでは、メモリ上の存在するワークフローのほとんどはイベント待ち状態にあります。イベントが来るまでワークフローは数分、数時間、あるいは数ヶ月ただ待ち続けることになります。イベント待ち状態になったワークフローをずっとメモリ上に保持するのはメモリの無駄となりますので、待ち状態になったワークフローをメモリからディスクなどに永続化させ、イベントが発生するまで待機させることで、メモリを開放することができます。

永続化とワークフローの種類
 もちろんシーケンシャルワークフローでも永続化を活用できます。シーケンシャルワークフローのイベントや時間待ちの際に、自動的に永続化が行われます。

 また、ワークフロー永続化には、耐障害性という側面もあります。ワークフローの実行状態を永続化しておくことで、ワークフローの特定の部分で障害が発生した場合にも、永続化した時点のワークフローをロードして再開することができます。

 WFでは、ワークフローの永続化サービスが標準で提供されており、ワークフローの状態管理をすべてWF側の永続化サービスに任せ、プログラマが意識することなく、イベント待ち状態になったワークフローを永続化させることができます。

 具体的には、永続化サービスは以下のタイミングで永続化処理を行います。

  • PersistOnCloseAttribute属性が付加されたアクティビティが完了するとき(トランザクション範囲を指定するためのTransactionScopeアクティビティなど)
  • ワークフローが完了するとき
  • ワークフローが強制終了するとき
  • ワークフローがアイドル状態になるとき
  • ワークフローインスタンスのUnloadメソッド、またはTryUnloadメソッドが呼び出されたとき

 多くのケースでは、ワークフロー内でDelayアクティビティを使って時間待ちを行ったり、EventDrivenアクティビティでイベント待ちをしたりする際に、ワークフローがアイドル状態になり、結果的に永続化が行われることになります。

 永続化サービスはSystem.Workflow.Runtime.Hosting.WorkflowPersistenceServiceという抽象クラスとして定義されています。WFではこのクラスを継承し、SQL Serverに永続化を行うSystem.Workflow.Runtime.Hosting.SqlWorkflowPersistenceServiceというクラスが提供されています。

永続化サービスの使い方

 では、SQL Serverへの永続化を行うSqlWorkflowPersistenceServiceクラスを使って、永続化サービスを試してみましょう。中編で作成した簡易注文管理アプリケーションに永続化サービスを追加し、どのように永続化が行われるかを確認しましょう。

動作環境

 SqlWorkflowPersistenceServiceクラスはSQL Server 2000/2005およびMSDE 2000上のデータベースに対してワークフローの永続化を行います。この記事ではSQL Server 2005 Express Editionを使用します。

永続化用データベースの作成

 Enterprise ManagerやSQL Server Management Studio Expressなどを使って永続化用データベースを作成します。今回はwftestという名前でデータベースを作成します。

wftestデータベースの作成(SQL Server Management Studio Express)
wftestデータベースの作成(SQL Server Management Studio Express)

 次に、永続化用のテーブルを作成します。

 「{Windowsフォルダ}\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL」にある「SqlPersistenceService_Schema.sql」「SqlPersistenceService_Logic.sql」を順に実行してください。これにより、CompletedScopeテーブルとInstanceStateテーブルが作成されます。

作成されたテーブル(SQL Server Management Studio Express)
作成されたテーブル(SQL Server Management Studio Express)

永続化サービスの登録

 中編で作成したStateMachineWorkflowSampleソリューションを開き、StateMachineWorkflowSampleApplicationプロジェクト(ホスティングWindowsアプリケーション)の「Form1.cs」を開きます。

 Form1クラスのコンストラクタにワークフローランタイムの初期化コードがありますので、そこに永続化サービスの登録処理を追加しましょう。

 コンストラクタ内を次のように修正してください。

Form1.cs - 永続化サービスの登録
using System.Workflow.Runtime.Hosting; //ファイル先頭部分に追加

……

public Form1()
{
  InitializeComponent();
  //ワークフロー ランタイムの生成
  workflowRuntime = new WorkflowRuntime();
  //(1) データ交換サービス(ExternalDataExchangeService)の生成
  ExternalDataExchangeService dataService =
      new ExternalDataExchangeService();
  //(2) ワークフロー ランタイムへのデータ交換サービスの登録
  workflowRuntime.AddService(dataService);
  //(3)ExternalDataExchange属性を持つ自分自身をデータ交換サービスに追加
  dataService.AddService(this);

  //後編で追加~ここから
  string connectionString =
    "Initial Catalog=wftest;Data Source=localhost;"
    + " Integrated Security=SSPI;"; //(1) 永続化用データベース接続文字列
  bool unloadOnIdle = true;
  TimeSpan instanceOwnershipDuration = TimeSpan.MaxValue;
  TimeSpan loadingInterval = new TimeSpan(0, 0, 5);
  // SQL永続化サービスを追加
  WorkflowPersistenceService persistenceService =
    new SqlWorkflowPersistenceService(
      connectionString,unloadOnIdle,instanceOwnershipDuration,
      loadingInterval); //(2) SQL Server永続化サービスの生成
  //(3) ワークフロー ランタイムへの永続化サービスの登録
  workflowRuntime.AddService(persistenceService);

  //(4)ワークフローのイベントごとにメッセージダイアログを表示
  workflowRuntime.WorkflowPersisted +=
    delegate(object sender, WorkflowEventArgs e)
    { MessageBox.Show(string.Format("Workflow {0} Persisted.",
      e.WorkflowInstance.InstanceId)); };
  workflowRuntime.WorkflowLoaded +=
    delegate(object sender, WorkflowEventArgs e)
    { MessageBox.Show(string.Format("Workflow {0} Loaded.",
      e.WorkflowInstance.InstanceId)); };
  workflowRuntime.WorkflowUnloaded +=
    delegate(object sender, WorkflowEventArgs e)
    { MessageBox.Show(string.Format("Workflow {0} Unloaded.",
      e.WorkflowInstance.InstanceId)); };
  workflowRuntime.WorkflowIdled +=
    delegate(object sender, WorkflowEventArgs e)
    { MessageBox.Show(string.Format("Workflow {0} Idled.",
      e.WorkflowInstance.InstanceId)); };
  workflowRuntime.WorkflowCompleted +=
    delegate(object sender, WorkflowCompletedEventArgs e)
    { MessageBox.Show(string.Format("Workflow {0} Completed.",
      e.WorkflowInstance.InstanceId)); };
  //後編で追加~ここまで

  workflowRuntime.StartRuntime();

}

 (1)で、先ほど作成した永続化用データベースへの接続文字列を指定していますので、適宜環境に合わせて修正してください。今回はWindows認証を用いてローカルに存在するSQL Server 2005 Express Editionに接続します。

 (2)で、SQL Serverへの永続化サービスであるSqlWorkflowPersistenceServiceを生成しています。第1引数(connectionString)は接続文字列を、第2引数(unloadOnIdle)はアイドル状態のワークフローを永続化するかどうかのフラグを、第3引数(instanceOwnershipDuration)はワークフローの所有権を保持する長さ、第4引数(loadingInterval)は読み込み間隔の長さを指定します。今回はアイドル状態になったワークフローを永続化させるため、第2引数にtrueを指定します。

 (3)で、ワークフローランタイムに永続化サービスを登録します。データ交換サービスの登録の場合と同様、AddServiceメソッドで登録を行います。

 (4)以降は、永続化サービスの登録処理ではなく、ワークフローのイベントごとにメッセージダイアログを表示する処理です。ワークフローの実行に合わせて、どんなイベントが発生しているのかを確認するために追加しています。

イベント名と概要
イベント名概要
WorkflowIdledワークフローがアイドル状態になった場合に発生
WorkflowPersistedワークフローが永続化された場合に発生
WorkflowUnloadedワークフローがメモリからアンロードされた場合に発生
WorkflowLoadedワークフローがメモリにロードされた場合に発生
WorkflowCompletedワークフローが完了した場合に発生

 以上で永続化サービスの組み込みは完了です。ワークフローランタイムの初期化以外に変更するところはありません。

次のページ
シリーズまとめ

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Vista時代のプログラミングモデル .NET Framework 3.0入門連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 土井 毅(ドイ ツヨシ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/1705 2007/10/03 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング