在一個連續的事務中回滾失敗的單個操作,並且禁止所有失敗消息框(包括警告和錯誤)
問題
我試圖實現一個失敗處理函數:禁止所有警告消息框並撤銷導致警告的操作。不過我找不到辦法禁止那些不是警告的消息框。
我的問題場景如下:
在一個外部命令裡創建多個Revit元素。這個過程可能在中途因為某種原因而失敗。但是我不希望每次失敗都彈出一個對話框讓用戶選擇繼續還是退出。我希望程序忽略掉導致失敗的那部分操作,繼續之後的操作。不過我需要記錄下所有發生的失敗,並且在整個外部命令結束時讓用戶知道發生了什麼。
回答
解決辦法裡需要兩個特殊的語句
- 在失敗處理函數中返回 FailureProcessingResult.ProceedWithRollBack;
- 對事務失敗處理設置調用 failureHandlingOptions.SetClearAfterRollback(true);
首先定義一個失敗處理類:
[csharp]
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;
}
}
然後在創建事務的時候按照如下方式指定失敗處理設置:
[csharp]
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 );
}