使用IDispatchMessageInspector记录WCF服务

时间:2014-09-12 09:05:30

标签: c# wcf logging idispatchmessageinspector

我试图记录请求&回应&来自我的WCF服务。我到现在所做的是:

public class OutputMessageInspector : IDispatchMessageInspector
{
    int lastLogId;

   public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
   {
       // Parse request & read required information
       // Insert request data into log tables
       // Set lastLogId to the id created above
   }

   public void BeforeSendReply(ref Message reply, object correlationState)
   {
       // Parse reply
       // Using lastLogId update the response column in database table
   }
}

一切正常,但我有一个问题:

AfterReceiveRequestBeforeSendReply必须同步,以便BeforeSendReply更新正确的记录。我想到的情况是同时从多个客户端调用服务,问题:

  • 不会lastLogId混乱并且在多个之间混乱 请求&反应?
  • BeforeSendReply处的此日志记录是否会有效    多个客户同时拨打服务很好吗?如是    那么请给我一个解释,以确保我的想法,如果没有    请为此提供更好的解决方案。

2 个答案:

答案 0 :(得分:4)

我同意@Schneiders解决方案,以便根据您的要求使用WCF日志记录。

但是要回答你的问题:

  

此日志记录是否会在BeforeSendReply上进行特别更新才能正常工作   多个客户同时呼叫服务?

不,不会。 IDispatchMessageInspector的实例在呼叫之间共享。

correlationState IDispatchMessageInspector支持调用特定数据,而不是使用成员属性。无论对象AfterReceiveRequest()返回什么,都将作为correlationState传递给BeforeSendReply()

换句话说,这样的事情应该有效:

public class OutputMessageInspector : IDispatchMessageInspector
{
   public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
   {
       // Parse request & read required information
       // Insert request data into log tables
       // Set lastLogId to the id created above
       return lastLogId
   }

   public void BeforeSendReply(ref Message reply, object correlationState)
   {
       // Parse reply
       int lastLogId = (int)correlationState;
   }
}

答案 1 :(得分:1)

首先:WCF具有 log the requests & responses 的内置功能,因此在您推出自己的解决方案之前可能值得研究。

对于您的问题,通常您将IDispatchMessageInspector应用为服务或端点行为,并挂起ApplyDispatchBehavior。在那里,您可能正在创建一个新的OutputMessageInspector并将其添加到DispatchRuntime.MessageInspectors集合。

只有在创建服务或端点时才会应用一次行为,因此您可以从中推断出只有一个DispatchRuntime并且您只创建一个MessageInspector,因此它将在所有请求/线程之间共享。

在这种情况下,您的OutputMessageInspector需要是"线程安全"。如果你在那里保持状态,你将需要同步访问它,以便它不会被扰乱。