我已经创建了 IDispatchMessageInspector 接口的自定义实现,并且我的代码运行良好 99%。
我的问题是,当 WCF 服务主机被杀死和/或释放我的类的实例时,我需要释放一些托管对象。我要释放的对象实现 IDisposable 但它们没有被处置。我已经浏览了 MSDN 库(更加困惑)和 SO 档案,但没有找到任何可以解决“WCF 服务主机何时/何处销毁 MessageInspectors?”这个问题的东西。
我需要在某个地方挂钩事件吗?我是否需要从 ServiceModel 命名空间实现更神秘的东西?
谁能给我一个正确方向的指针?
编辑 1:澄清
目前,我正在使用自动网络服务器在 IDE 中运行。一旦投入生产,我最终无法控制主机,可能是任何有效的服务器主机选择。
MyCore.My 和 MyCore.MyProperties 对象是我试图在 WCF 服务器主机被杀死/退回时处理的对象。
即使我杀死了网络服务器进程(任务栏中的那些东西),也永远不会调用 Dispose()。
编辑 2:添加了代码片段。
using /* snip */
using MyCore = Acme.My;
namespace My.SOAP
{
public class MyMessageInspector : IDispatchMessageInspector
{
protected static MyCore.My _My;
protected static MyCore.MyProperties _MyProps;
protected static ConcurrentDictionary<string, MyCore.AnotherSecretThing> _anotherSecretThings = new ConcurrentDictionary<string, MyCore.AnotherSecretThing>();
protected static void InitMy()
{
if (_My != null) return;
_MyProps = new MyCore.MyProperties();
MyCore.MySqlDatabaseLogger logger = new MyCore.MySqlDatabaseLogger(_MyProps);
_My = new MyCore.My(logger);
}
public MyMessageInspector()
{
InitMy();
}
public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
MyMessageHeader header = null;
try
{
// find My header
Int32 headerPosition = request.Headers.FindHeader(MyMessageHeaderKey.MyHeaderElementName, MyMessageHeaderKey.MyNamespace);
// get reader
XmlDictionaryReader reader = request.Headers.GetReaderAtHeader(headerPosition);
// get My header object
header = MyMessageHeader.ReadHeader(reader);
// add to incoming messages properties dictionary
OperationContext.Current.IncomingMessageProperties.Add(MyMessageHeaderKey.MyHeaderElementName, header);
}
catch (Exception ex)
{
// log via ExceptionHandlingBlock
}
MyCore.SecretThings SecretThings = CreateSecretThings(/* snip */);
return SecretThings.Id;
}
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
MyCore.SecretThings req = _My.GetSecretThingsOnThread();
// if we didn't find the SecretThings, there is nothing to stop() and no data to put in the MessageHeaders
if (req == null) return;
MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);
reply = buffer.CreateMessage();
var MyHeader = new MyMessageHeader(/* snip */);
reply.Headers.Add(MyHeader);
req.Stop(MyCore.Status.SUCCESS);
}
protected MyCore.SecretThings CreateSecretThings(string key, Dictionary<string, string> ids)
{
/* snip */
return _My.GetSecretThings(/* snip */);
}
}
}