我有一个旧的MonoRail / ActiveRecord我也做过一些工作。
最近我决定将应用程序升级到Castle Trunk& NHibernate 2.1.0.4000 GA我现在发现了运行测试的一些问题:
首先关闭 - 当使用TestDriven.Net运行针对数据库的集成测试时,它会完全崩溃TestDriven.Net,或者所有测试都完成执行,然后TestDriven.Net挂起。这在升级之前从未发生过。
当TestDriven.Net崩溃时,这是写入事件日志的内容:
故障桶1467169527,类型1 事件名称:APPCRASH 回复:不可用 驾驶室ID:0
问题签名: P1:ProcessInvocation86.exe P2:2.22.2468.0 P3:4a26845c P4:KERNELBASE.dll P5:6.1.7600.16385 P6:4a5bdbdf P7:e053534f P8:0000b727 P9: P10:
第二件事 - 当代理类正在进行Finalize()时,会记录异常,如下所示 - 似乎只有一次记录这个异常,就像TestDriven.Net崩溃一样。
以下是异常的堆栈跟踪:
NHibernate.LazyInitializationException:
Initializing[MyApp.Core.Models.TestExecutionPackage#15d9eb96-faf0-4b4b-9c5c-9cd400065430]-Could not initialize proxy - no Session.
at NHibernate.Proxy.AbstractLazyInitializer.Initialize()
at NHibernate.Proxy.AbstractLazyInitializer.GetImplementation()
at NHibernate.ByteCode.Castle.LazyInitializer.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.TestExecutionPackageProxy.Finalize()
同样的行为也会导致我们的CI服务器上的MsBuild崩溃。
真正奇怪的是理论上应该根据MSDN文档吞下Finalize()中抛出的异常:
http://msdn.microsoft.com/en-us/library/system.object.finalize(VS.71).aspx
如果 Finalize 或覆盖 Finalize 会引发异常,运行时会忽略该异常,终止 Finalize 方法,并继续完成过程
有人想到吗?
答案 0 :(得分:0)
从来没有深入到这个问题的底层,但我最终通过创建自己的LazyInitializer实现来实现一个相当简单的工作,我在调用时检查Finalize方法,如下所示:
/// <summary>
/// Invoke the actual Property/Method using the Proxy or instantiate the actual
/// object and use it when the Proxy can't handle the method.
/// </summary>
/// <param name="invocation">The <see cref="IInvocation"/> from the generated Castle.DynamicProxy.</param>
public virtual void Intercept(IInvocation invocation)
{
try
{
if (invocation.Method.Name == "Finalize")
{
return;
}
if (_constructed)
{
// let the generic LazyInitializer figure out if this can be handled
// with the proxy or if the real class needs to be initialized
invocation.ReturnValue = base.Invoke(invocation.Method, invocation.Arguments, invocation.Proxy);
// the base LazyInitializer could not handle it so we need to Invoke
// the method/property against the real class
if (invocation.ReturnValue == InvokeImplementation)
{
invocation.ReturnValue = invocation.Method.Invoke(GetImplementation(), invocation.Arguments);
return;
}
else
{
return;
}
}
else
{
// TODO: Find out equivalent to CGLIB's 'method.invokeSuper'.
return;
}
}
catch (TargetInvocationException tie)
{
// Propagate the inner exception so that the proxy throws the same exception as
// the real object would
Exception_InternalPreserveStackTrace.Invoke(tie.InnerException, new Object[] { });
throw tie.InnerException;
}
}
答案 1 :(得分:0)
当我迁移到2.1.2版本的NHibernate时,我遇到了同样的问题。我已经为LinFu Proxy更改了Castle,然后一切正常。希望这有助于。