Dispose神秘地调用了我的对象
本文关键字:我的 对象 调用 Dispose | 更新日期: 2023-09-27 18:21:25
我遇到了一个奇怪的问题:
我有一个对象(在简化视图中)看起来像这样:
public class LogService : ILogProvider
{
private ServiceHost host;
public void Open()
{
// Open Service
}
public void Dispose()
{
// host.Dispose();
}
}
此对象正被引用为其他类上的字段。
偶尔在我的应用程序中,我会重新创建服务(我想这会导致LogService对象被收集)。
然而,我看到LogService的Dispose()方法正在被调用,尽管我在代码库中没有直接调用它!
调试时,Visual Studio中的调用程序"调用堆栈"是"外部"的,因此我无法查看它。
是什么原因造成的?当调用它时,host字段为null,并抛出一个nullreference。
以下是失败的调用堆栈:
Executer.dll!Executer.LogService.Dispose()行54+0x6字节C#System.ServiceModel.dll!System.ServiceModel.Dispatcher.InstanceBehavior.InstanceProvider.ReleaseInstance(System.ServiceModel.InstanceContextinstanceContext,对象实例)+0x25字节
System.ServiceModel.dll!System.ServiceModel.Dispatcher.InstanceBehavior.ReleaseInstance(System.ServiceModel.InstanceContextinstanceContext,对象实例)+0x35字节
System.ServiceModel.dll!System.ServiceModel.InstanceContext.SetUserObject(对象newUserObject)+0x4e字节
System.ServiceModel.dll!System.ServiceModel.InstanceContext.Unload()+0xf字节System.ServiceModel.dll!System.ServiceModel.InstanceContext.OnClose(System.TimeSpan超时)+0x1f字节
System.ServiceModel.dll!System.ServiceModel.Channels.CommunicationObject.Close(System.TimeSpan超时)+0x172字节
System.ServiceModel.dll!System.ServiceModel.InstanceContext.CloseIfNotBusy()+0x76字节System.ServiceModel.dll!System.ServiceModel.InstanceContext.NotifyEmpty(System.ServiceModel.InstanceContextinstanceContext)+0xb字节
System.ServiceModel.dll!System.ServiceModel.ServiceChannelManager.OnEmpty()+0x16字节System.ServiceModel.dll!System.ServiceModel.Channels.LifetimeManager.DecrementBusyCount()+0xbc字节System.ServiceModel.dll!System.ServiceModel.ServiceChannelManager.ChannelRemoved(System.ServiceModel.Channels.IChannel通道)+0x37字节
System.ServiceModel.dll!System.ServiceModel.ServiceChannelManager.RemoveChannel(System.ServiceModel.Channels.IChannel通道)+0x42字节
System.ServiceModel.dll!System.ServiceModel.ServiceChannelManager.OnChannelClosed(对象sender,System.EventArgs args)+0x16字节
System.ServiceModel.dll!System.ServiceModel.Channels.CommunicationObject.OnClosed()+0xd5字节System.ServiceModel.dll!System.ServiceModel.Channels.CommunicationObject.Artrt()+0xcf字节System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.OnInnerChannelFaulted(对象发送方,System.EventArgs e)+0x46字节
我没有答案,但有这样的想法。你可能是对的。这意味着ServiceHost在LogService之前被释放。
如果这是真的,那么我不明白为什么LogService中的ServiceHost为null。只有当ServiceHost的处理也会使所有对它的引用无效时,才能做到这一点。我觉得很难相信,但也可能是我缺乏知识(也许有人可以证实)。所以我创建了一个小测试,它应该通过抛出一个null引用异常来验证这一点,但它没有。
public interface ILogProvider : IDisposable
{
void Open();
}
public class LogService : ILogProvider
{
private readonly ServiceHost host;
public LogService(ServiceHost host)
{
this.host = host;
}
public void Open()
{
// Open Service
}
public void Dispose()
{
host.Dispose();
}
}
public class ServiceHost : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~ServiceHost()
{
Dispose(false);
}
public virtual void Dispose(bool disposing)
{
if (disposing)
{
//do managed cleanup
}
// do unmanaged cleanup here
}
}
internal class Program
{
private static void Main(string[] args)
{
var host = new ServiceHost();
using (LogService log = new LogService(host))
{
host.Dispose();
}
}
}
测试首先处理ServiceHost
,然后在不引发异常的情况下调用对LogService
的处理。因此,除非ServiceHost
的处理从根本上以不同的方式实现(这很容易),否则您必须检查LogService
是如何创建的。它真的总是引用ServiceHost
吗?
希望这能帮助你朝着正确的方向前进。此外,如果您解决了问题,请提供答案。