我遇到了一个奇怪的问题:
我有一个对象(在简化视图中)看起来像这样:
public class LogService : ILogProvider
{
private ServiceHost host;
public void Open()
{
// Open Service
}
public void Dispose()
{
// host.Dispose();
}
}
此对象被引用为某个其他类的字段。
偶尔在我的应用程序中,我正在重新创建服务(我猜这会导致收集LogService对象)。
但是,我看到正在调用LogService的Dispose()方法,虽然我不会在我的代码库中直接调用它!
调试这个,Visual Studio“Call Stack”中的调用者是“外部”,所以我无法查看它。
这会导致什么?在调用它时,host字段为null,并抛出null引用。
这是失败的问号:
Executer.dll!Executer.LogService.Dispose()第54行+ 0x6字节C#System.ServiceModel.dll!System.ServiceModel.Dispatcher.InstanceBehavior.InstanceProvider.ReleaseInstance(System.ServiceModel.InstanceContext instanceContext,object instance)+ 0x25 bytes
System.ServiceModel.dll!System.ServiceModel.Dispatcher.InstanceBehavior.ReleaseInstance(System.ServiceModel.InstanceContext instanceContext,object instance)+ 0x35 bytes
System.ServiceModel.dll!System.ServiceModel.InstanceContext.SetUserObject(对象 newUserObject)+ 0x4e bytes
System.ServiceModel.dll!System.ServiceModel.InstanceContext.Unload() + 0xf bytes 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 bytes System.ServiceModel.dll!System.ServiceModel.InstanceContext.NotifyEmpty(System.ServiceModel.InstanceContext instanceContext)+ 0xb bytes
System.ServiceModel.dll!System.ServiceModel.ServiceChannelManager.OnEmpty() + 0x16字节System.ServiceModel.dll!System.ServiceModel.Channels.LifetimeManager.DecrementBusyCount() + 0xbc bytes 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 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.CommunicationObject.OnClosed() + 0xd5 bytes System.ServiceModel.dll!System.ServiceModel.Channels.CommunicationObject.Abort() + 0xcf bytes System.ServiceModel.dll!System.ServiceModel.Channels.ServiceChannel.OnInnerChannelFaulted(object sender,System.EventArgs e)+ 0x46 bytes
答案 0 :(得分:0)
我没有你的答案,但有这个想法。你可能是对的。这意味着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
?
希望这有助于您朝着正确的方向前进。如果你解决了,请提供答案。