Я не уверен, что было бы «лучшим» для архитектуры WCF, но вы должны подумать о том, чтобы установить InstanceContextMode в Single, поскольку вы, вероятно, будете выполнять множество шагов синхронизации для того, что вы хотите сделать Вот.
Как насчет чего-то подобного? Вам, очевидно, потребуется выполнить некоторую синхронизацию в самом словаре, но, по крайней мере, это начало.
private IDictionary<string, RequestToken> RequestTokens =
new Dictionary<string, RequestToken>();
public MyResponse MyMethod(MyRequest request)
{
// get the MD5 for the request
var md5 = GetMD5Hash(request);
// check if another thread is processing/has processed an identical request
RequestToken token;
if (RequestTokens.TryGetValue(md5, out token))
{
// if the token exists already then wait till we can acquire the lock
// which indicates the processing has finished and a response is ready
// for us to reuse
lock (token.Sync)
{
return token.Response;
}
}
else
{
var token = new Token(md5);
lock (token.Sync)
{
RequestTokens.Add(md5, token);
// do processing here..
var response = ....
token.Response = response;
return response;
}
}
}
private class RequestToken
{
private readonly object _sync = new object();
public RequestToken(string md5)
{
MD5 = md5;
}
public string MD5 { get; private set; }
public object Sync { get { return _sync; } }
public MyResponse Response { get; set; }
}
Для меня, это то, что я хотел бы абстрагироваться от моей бизнес-логики, и я лично использую PostSharp и написать небольшой атрибут для обработки всего этого.
Я написал атрибут Memoizer, который делает что-то подобное в строках ответов на кеширование на основе запроса, но без шагов синхронизации, поэтому вы, вероятно, можете взглянуть на то, что я сделал, и изменить его соответственно для достижения того, что вы после.
Правильно ли считать, что это чрезвычайно дорогостоящая операция, которая требует сложной системы координации перекрестных запросов? – RQDQ
есть. запрос занимает несколько секунд и не может быть кэширован. – NickD