Building Coder - 失败回滚(Failure Rollback)
在一个连续的事务中回滚失败的单个操作,并且禁止所有失败消息框(包括警告和错误)
问题
我试图实现一个失败处理函数:禁止所有警告消息框并撤销导致警告的操作。不过我找不到办法禁止那些不是警告的消息框。
我的问题场景如下:
在一个外部命令里创建多个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 );
}
补充:软件开发 , C# ,