Building Coder(Revit 二次開發) - 失敗回滾(Failure Rollback)

原文鏈接:Failure Rollback


在一個連續的事務中回滾失敗的單個操作,並且禁止所有失敗消息框(包括警告和錯誤)


問題

我試圖實現一個失敗處理函數:禁止所有警告消息框並撤銷導致警告的操作。不過我找不到辦法禁止那些不是警告的消息框。


我的問題場景如下:

在一個外部命令裏創建多個Revit元素。這個過程可能在中途因爲某種原因而失敗。但是我不希望每次失敗都彈出一個對話框讓用戶選擇繼續還是退出。我希望程序忽略掉導致失敗的那部分操作,繼續之後的操作。不過我需要記錄下所有發生的失敗,並且在整個外部命令結束時讓用戶知道發生了什麼。

回答

解決辦法裏需要兩個特殊的語句
- 在失敗處理函數中返回 FailureProcessingResult.ProceedWithRollBack;
- 對事務失敗處理設置調用 failureHandlingOptions.SetClearAfterRollback(true);


首先定義一個失敗處理類:
public class FailureHandler : IFailuresPreprocessor
{
  public string ErrorMessage { set; get; }
  public string ErrorSeverity { set; get; }
 
  public FailureHandler()
  {
    ErrorMessage = "";
    ErrorSeverity = "";
  }
 
  public FailureProcessingResult PreprocessFailures( FailuresAccessor failuresAccessor )
  {
    IList<FailureMessageAccessor> failureMessages = failuresAccessor.GetFailureMessages();
 
    foreach( FailureMessageAccessor failureMessageAccessor in failureMessages )
    {
      // We're just deleting all of the warning level 
      // failures and rolling back any others
 
      FailureDefinitionId id = failureMessageAccessor.GetFailureDefinitionId();
 
      try
      {
        ErrorMessage = failureMessageAccessor.GetDescriptionText();
      }
      catch
      {
        ErrorMessage = "Unknown Error";
      }
 
      try
      {
        FailureSeverity failureSeverity = failureMessageAccessor.GetSeverity();
 
        ErrorSeverity = failureSeverity.ToString();
 
        if( failureSeverity == FailureSeverity.Warning )
        {
		  // 如果是警告,則禁止消息框
          failuresAccessor.DeleteWarning( failureMessageAccessor );
        }
        else
        {
		  // 如果是錯誤:則取消導致錯誤的操作,但是仍然繼續整個事務
          return FailureProcessingResult.ProceedWithRollBack;
        }
      }
      catch 
      {
      }
    }
    return FailureProcessingResult.Continue;
  }
}

然後在創建事務的時候按照如下方式指定失敗處理設置:
Transaction transaction = new Transaction( doc );
 
FailureHandlingOptions failureHandlingOptions = transaction.GetFailureHandlingOptions();
FailureHandler failureHandler = new FailureHandler();
failureHandlingOptions.SetFailuresPreprocessor( failureHandler );
// 這句話是關鍵
failureHandlingOptions.SetClearAfterRollback( true );
transaction.SetFailureHandlingOptions( failureHandlingOptions );


transaction.Start( "Transaction Name" );
// Do something here that causes the error
// ......
transaction.Commit();


// 這段代碼只是簡單地用一個 WinForm 對話框顯示在失敗處理函數中保存的失敗記錄。
// 你可以在實際應用中對這些失敗記錄做任何處理。
if( failureHandler.ErrorMessage != "" )
{
System.Windows.Forms.MessageBox.Show( failureHandler.ErrorSeverity + " || " + failureHandler.ErrorMessage );
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章