【发布时间】:2012-06-26 12:22:14
【问题描述】:
我们有多个 WCF 服务都使用 InstanceContextMode=PerCall 并且所有 WCF 服务实例都是通过使用 Unity (IOC) 和实现 IInstanceProvider 生成的。
关联标识符用于审计具有相同标识符的所有方法调用和数据库进程。
为了实现这一点,通过实现 IDispatchBehavior 来创建端点行为,并在 AfterReceiveRequest 方法中生成一个 guid 并将其分配给 ThreadStatic (CommonData) 属性。此属性可以在应用程序的所有层中访问。以下代码块显示了 CommonData 的填充以及 CommonData 类;
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
CommonData.ClearDictionary();
//the lines between are deleted as they are not relevant to the question
CommonData.Current.Add(MessageHeaderCodes.CorrelationId, Guid.NewGuid().ToString());
return null;
}
和通用数据类:
public class CommonData
{
[ThreadStatic]
private static Dictionary<string, string> headerData;
public static Dictionary<string, string> Current
{
get
{
if (headerData == null)
{
headerData = new Dictionary<string, string>();
}
return headerData;
}
}
private CommonData()
{
}
public static string GetHeader(string header)
{
string headerValue = string.Empty;
KeyValuePair<string, string> headerKeyValuePair = CommonData.Current.SingleOrDefault(p => p.Key == header);
headerValue = headerKeyValuePair.Value;
return headerValue;
}
public static void ClearDictionary()
{
Current.Clear();
}
}
这里的问题如下; 在某些服务中,开发人员报告相关标识符返回 null。由于问题是间歇性的,目前不可能有完整的堆栈跟踪。此外,他们表示重置 IIS 可以暂时解决此问题。
感谢任何帮助...
【问题讨论】:
-
你究竟是如何检索标识符的(我猜是通过 GetHeader 方法)?
-
我没有从客户端获取标识符,我只是在 AfterReceiveRequest 方法中为每个调用创建一个新标识符; CommonData.Current.Add(MessageHeaderCodes.CorrelationId, Guid.NewGuid().ToString());
-
是的,但是您稍后会尝试以某种方式检索它,对吗?如何?如果不是 - 那么究竟什么是 null?
-
这实际上是确切的问题:) 我创建了一个 guid,以便将所有正在运行的方法与数据库更改相关联。例如,如果调用了一个服务方法,则会生成一个带有生成 id 的日志;所有数据库更改也使用相同的 id。因此,可以将服务调用映射到方法调用和数据库更改。
-
好吧,也许我明白了,但是你为什么需要字典。一个字符串值(每个线程)就足够了,不是吗?