1

Windows ステート マシンのワークフローでエンド ユーザーと通信できるようにしようとしています。StateActivity 内で実装しようとしている一般的なパターンは次のとおりです。

StateInitializationActivity: 質問に対する回答を要求するメッセージをユーザーに送信します (例: 「このドキュメントを承認しますか?」)。...
...EventDrivenActivity: ユーザーが送信した回答を処理する
StateFinalizationActivity: キャンセル メッセージ (例: 「このドキュメントを承認しますか?」)文書は撤回され、承認は必要ありません)

StateActivity が「リーフ状態」(つまり、子状態がない) の場合、これはすべて正常に機能します。ただし、状態の再帰合成を使用したい場合は機能しません。非リーフ ステートの場合、StateInitialization と StateFinalization は実行されません (この動作は、Reflector を使用して StateActivity ソース コードを調べて確認しました)。EventDrivenActivity はまだリッスンしていますが、エンド ユーザーは何が起こっているのかわかりません。

StateInitialization については、これを回避する 1 つの方法は、EventDrivenActivity とゼロ遅延タイマーに置き換えることだと思いました。StateFinalization をどうするか悩んでいます。

だから - リーフ以外の状態であっても、状態のファイナライズアクティビティを常に実行する方法について誰か考えがありますか?

4

3 に答える 3

1

「ネストされた状態」の構造が「子」を含む「親」の 1 つであるのは残念なことですが、デザイナー UI はこの概念を強化しています。したがって、あなたが考えているように考えるのは非常に自然で直感的です。それは間違っているので残念です。

本当の関係は、「一般」→「特定」のいずれかです。その事実上、階層的なクラス構造です。もっと身近なそのような関係を考えてみましょう:-

public class MySuperClass
{
    public MySuperClass(object parameter) { }
    protected void DoSomething() { }
}

public class MySubClass : MySuperClass
{
    protected void DoSomethingElse() { }
}

ここは からMySubClass継承DoSomethingSuperClassます。SuperClassただし、デフォルトのコンストラクターがないため、上記は壊れています。また、 のパラメーター化されたコンストラクターは にSuperClass継承されませんSubClass。実際、論理的には、サブクラスはスーパークラスのコンストラクタ (またはデストラクタ) を継承することはありません。(はい、デフォルトのコンストラクターを配線する魔法がいくつかありますが、それは実質よりも砂糖です)。

同様に、別の StateActivities に含まれる StateActivities 間の関係StateActivityは、実際には、含まれるアクティビティがコンテナーの特殊化であるということです。含まれている各アクティビティは、コンテナの一連のイベント ドリブン アクティビティを継承します。ただし、含まれている各 StateActivity は、他の状態と同様に、ワークフロー内のファースト クラスの個別の状態です。

実際に含まれるアクティビティは抽象化され、遷移することはできず、重要なことに、別の状態の「内部」に遷移するという実際の概念はありません。ひいては、そのような外的状態を離れるという概念もありません。その結果、含まれている StateActivity の初期化またはファイナライズは行われません。

デザイナーの癖により、StateInitialization と StateFinalization を追加してから、StateActivities を状態に追加できます。逆に試してみると、デザイナーは初期化とファイナライズが実行されないことを知っているため、許可しません。

これは実際にはあなたの質問に答えていないことを認識しており、この場合「それはできません」とは言いたくないのですが、できれば少しハッキーになります。

于 2009-11-25T18:33:54.517 に答える
0

問題を解決する別の方法を考えました。もともと、通信には WF 3.5 で提供されている WCF 統合の SendActivity と ReceiveActivity を使用することを念頭に置いていました。

しかし、最終的には、これらのアクティビティを無視して、ローカル サービスで独自の IEventActivity を実装する方が簡単であるという結論に達しました。IEventActivity.Subscribe を使用して、回答する質問があることをユーザーに示し、IEventActivity.Unsubscribe を使用して質問をキャンセルできます。これは、State の初期化ブロックと終了ブロックで個別のアクティビティが必要ないことを意味します。メッセージのルーティングはワークフロー キューを使用して手動で行われ、ユーザーの応答は適切な名前でキューに追加されます。キュー名に Guid を使用しました。これらは、IEventActivity.Subscribe 呼び出し中にユーザーに渡されます。

これを行う方法を理解するために、MSDN の「ファイル システム ウォッチャー」の例を使用しました。また、この記事は非常に有益であることがわかりました: http://www.infoq.com/articles/lublinksy-workqueue-mgr

于 2010-01-29T16:29:49.173 に答える
0

よし、最終的に決めたのはこれ。エンド ユーザーとのコミュニケーションに関係する州への出入りに対応するアクティビティ イベントを検索するカスタム追跡サービスを作成しました。このサービスは、状態に入るとユーザーの決定をデータベースに入力し、状態を離れると決定を削除します。ユーザーはデータベースにクエリを実行して、ワークフローが待機している決定を確認できます。ワークフローは、EventDrivenActivity の ReceiveActivity を使用してユーザーの応答をリッスンします。これは、親の「スーパーステート」での決定にも機能します。これはまさに「追跡サービス」の目的ではないかもしれませんが、機能しているようです

于 2009-12-09T15:54:53.127 に答える