2

単一のワークフロー定義 (xamlx) と永続化のための SqlInstanceStore を使用して、IIS で実行されている WF4 プロジェクトを考えてみましょう。xamlx を直接ホストする代わりに、顧客ごとに個別のエンドポイントで専用の WorkflowServiceHost をスピンアップする WorkflowServiceHostFactory をホストします。

ワークフロー定義の新しいバージョンが必要になるまで、これはしばらくの間正常に動作していました。ワークフロー サービスとのすべての対話は、必要なバージョンを識別するのに十分なほどスマートなビジネス ロジックでラップされているため、この自作のバージョン管理は、新しく開始されたワークフロー (Flow.xamlx と Flow1.xamlx の両方) に対して適切に機能します。

ただし、この変更の前に開始されたワークフローは再アクティブ化に失敗します (ポストでサービスホストが UnknownMessageReceived 例外をスローします)。WF はワークフローを再アクティブ化できない理由 (間違ったバージョン、インスタンスが見つからない、ロックなど) を説明する際に過度に冗長ではないため、SQL プロファイラーをデータベースにアタッチしました。

WorkflowServiceHost がクエリで使用する「WorkflowServiceType」が、保存されているインスタンスの WorkflowServiceType とは異なることが判明しました。おそらくこれが、永続化されたインスタンスの検出に失敗する理由です。

私は同じ xamlx をインスタンス化していると確信しているので、この値がどこから来ているのか理解できません。この Guid の計算に使用されるパラメーター、環境 (サイト名) は重要ですか、ワークフローを再アクティブ化するにはどうすればよいですか?

4

1 に答える 1

3

最後に、System.Activities.DurableInstancing を逆コンパイルしました。SqlWorkflowInstanceStore の WorkflowHostType の唯一のセッターは、ExtractWorkflowHostType にありました。

private void ExtractWorkflowHostType(IDictionary<XName, InstanceValue> commandMetadata)
{
    InstanceValue instanceValue;
    if (commandMetadata.TryGetValue(WorkflowNamespace.WorkflowHostType, out instanceValue))
    {
        XName xName = instanceValue.Value as XName;
        if (xName == null)
        {
            throw FxTrace.Exception.AsError(new InstancePersistenceCommandException(SR.InvalidMetadataValue(WorkflowNamespace.WorkflowHostType, typeof(XName).Name)));
        }
        byte[] bytes = Encoding.Unicode.GetBytes(xName.ToString());
        base.Store.WorkflowHostType = new Guid(HashHelper.ComputeHash(bytes));
        this.fireRunnableInstancesEvent = true;
    }
}

呼び出し元のコード パスを明確に解きほぐすことはできなかったので、実行時に WinDbg/SOS を IIS にアタッチし、HashHelper.ComputeHash を壊して調べる必要がありました。

ハッシュ計算に使用される XName を取得できました。この XName には、servicefile と等しいローカル名と、[サイト名]/[パス]/ と等しい名前空間があります。

最終的に、WorkflowHostType の計算は次のようになります。

var xName = XName.Get("Flow.xamlx.svc", "/examplesite/WorkflowService/1/");
var bytes = Encoding.Unicode.GetBytes(xName.ToString());
var WorkflowHostType = new Guid(HashHelper.ComputeHash(bytes));

結論: どうやらワークフローは、サービスのファイル名、サイト名、およびパスがすべて開始時と同じ (大文字と小文字を区別) である場合にのみ再水和できます。

于 2013-08-29T07:42:24.103 に答える