2013-10-09 47 views
3

內編程方式終止工作流我有一個Windows工作流基礎服務內舉辦了碼活動,我要終止基於一些價值我從數據庫中檢查工作流程。我不想使用拋出異常方法,並且我需要從「代碼活動」代碼中,而不是從設計器中執行此操作。我仍然是初學者,在WWF,我嘗試了下面的方法,它創建一個工作流應用程序,並在代碼活動的當前實例上初始化它,但它不起作用。我需要首先捕獲當前活動實例的父級工作流應用程序,然後調用Terminate方法。C#代碼從活動WF 4.0

WorkflowApplication wfApp = new WorkflowApplication(this); 
    wfApp.Terminate("The following workflow is terminating"); 

非常感謝您對這個

回答

1

幫助,您可以把WorkflowApplication在應用上下文擴展然後將可通過ActivityContext類。

// Add the application to it's own context 
_workflowApplication.Extensions.Add(_workflowApplication); 

// Access the application in your activity 
var application = context.GetExtension<WorkflowApplication>(); 
application.BeginTerminate(new WorkflowException(error), null, null); 
+0

感謝您的回覆,也許我的回答是愚蠢的,我試過了,它給了我對象引用未設置爲對象的實例。我應該從Activity外部傳遞WorkflowApplication變量作爲參數嗎? –

+0

@HassanMokdad你需要將應用程序添加到它的擴展 - 有點不正常,但我找到了最簡單的方法。答案已更新。 – Slugart

+0

這不完全是最正確的方式。您將約束附加到工作流,以使其始終具有* WorkflowApplication *擴展名。使用[TerminateWorkflow](http://msdn.microsoft.com/zh-cn/library/system.activities.statements.terminateworkflow.aspx)。 – Joao

5

要優雅地終止,只需使用TerminateWorkflow作爲兒童活動。這將調用WorkflowApplication.Completed操作。

public class CanceledActivity : NativeActivity 
{ 
    private readonly TerminateWorkflow terminateWorkflow = new TerminateWorkflow 
     { 
      Reason = "Reason why I'm terminating!" 
     }; 

    protected override void CacheMetadata(NativeActivityMetadata metadata) 
    { 
     metadata.AddImplementationChild(terminateWorkflow); 
    } 

    protected override void Execute(NativeActivityContext context) 
    { 
     context.ScheduleActivity(terminateWorkflow); 
    } 
} 

或者你也可以拋出一個異常,但這會調用WorkflowApplication.OnUnhandledException

public class CanceledActivity : NativeActivity 
{ 
    protected override void Execute(NativeActivityContext context) 
    { 
     throw new Exception("this will not gracefully terminate the workflow") 
    } 
} 

還有很多其他的方式,也取決於你想要做什麼以及什麼時候做它。請記住,由於其異步特性,工作流程只會在可能時終止。

+0

這類工作,但我找不到從調用終止的活動中獲取OutArguments的方法。此外,它將ActivityInstanceState設置爲Faulted,而理想情況是返回Closed的一種解決方案(有意完成)。希望wf4在Visio中有一個合適的f#* $ *%終端節點。 – RJB

+0

@RJB我完全明白你在說什麼,並且從業務經理的角度出發,繪製業務規則,這是完全有道理的,但是,如果你處於這種情況,90%的時間你應該退後一步,重新思考因爲在編碼世界中終止某些東西感覺不自然。應該將WF4視爲一種編程語言,通過它可以使用活動繪製算法。用真正的語言,如果你在中間終止一個方法,那是因爲你只是在做一些事情(而不是計算某些東西),並且無論如何你都會返回void而不需要輸出參數。 – Joao

+0

這就是說,如果您需要從剛剛執行的(一半)工作流中取回信息,只需將該信息寫入某處即可,就像在無效方法中那樣。看看WF4 lib代碼的特定位置,TerminateWorkflow是一個衆所周知的活動,當使用它時,你基本上說「*我知道我打破了事情,搞亂了狀態和執行,但是請儘快終止工作流程您可以*」。這就是爲什麼它以Faulted狀態結束的原因,這就是爲什麼要返回輸出參數非常困難的原因,就像在執行過程中中斷了工作流狀態一樣。 – Joao

0

在我看來,實際上你在當前想要使用的一項活動中有兩項活動。 您要求的內容在流程圖(即Visio)中是不可能的,要麼是因爲一個活動只有一個可以鏈接到下一個活動(即結束狀態)的退出,您需要一個決策塊才能夠一條不同的路線。

這是你嘗試轉換成流程圖什麼的例子:從方法的體內

public int CalculatePrice(string parameters) 
{ 
    // Calculate result. 
    var price = 5; 

    // Are we done? 
    if (!IsVATNeeded(price)) 
    { 
     return price; 
    } 

    // Do more calculations. 
    price = price * vat; 

    return price; 
} 

返回是一個代碼氣味指出,有必要重新思考的工作流程。一個健康的方法只有一個回報。 也就是說

public int CalculatePrice(string parameters) 
{ 
    var price = CalculatePriceWithoutVAT(parameters); 

    if (IsVATNeeded(parameters)) 
    { 
     price = ApplyVAT(price); 
    } 

    return price; 
} 

現在,第二種方法可以直接轉換爲流程圖/工作流程。 enter image description here

如果您有其他情況,請提供樣本流程圖或其他圖表。 經驗法則是,如果您無法繪製流程圖,狀態機或序列圖,則無法使用Microsoft Workflow實施。

請注意,可以創建由其他活動組成的創建活動,以便將上圖中的活動嵌入到單個活動中並隱藏詳細信息。這與代碼示例中的CalculatePrice方法相同。來電者實際上不必知道價格是如何計算的。