ASP.NET Web API: 一个很长的方法,如何保证调用一次
ASP.NET Web API: One long method, how to ensure it'll be called once
我有一个很长的 运行 Web 服务请求,完成后应该缓存在服务器端。我的问题是 - 我不知道如何防止它在第一次请求后被缓存之前被调用 concurrently/simultaneously。
我的想法是我应该创建一个数据请求 Task
并将其存储在并发字典中。所以每个其他请求都应该检查 Task
是否已经 运行 并等待它完成。
我已经结束了:
private static ConcurrentDictionary<string, Task> tasksCache = new ConcurrentDictionary<string, Task>();
public static T GetFromCache<T>(this ICacheManager<object> cacheManager, string name, Func<T> func)
{
if (cacheManager.Exists(name))
return (T)cacheManager[name];
if (tasksCache.ContainsKey(name))
{
tasksCache[name].Wait();
return (tasksCache[name] as Task<T>).Result;
}
var runningTask = Task.Run(() => func.Invoke());
tasksCache[name] = runningTask;
runningTask.Wait();
var data = runningTask.Result;
cacheManager.Put(name, data);
tasksCache.TryRemove(name, out Task t);
return data;
}
但这看起来很乱。有没有更好的方法?
我会考虑将这些包装在每个任务的 Lazy<T>
中,它具有用于控制并发初始化的内置语义。
This example 演示了如何使用 Lazy<T>
class 来提供从多个线程访问的惰性初始化。
您需要指定合适的 LazyThreadSafetyMode
。
Fully thread safe; uses locking to ensure that only one thread initializes the value. ExecutionAndPublication
我有一个很长的 运行 Web 服务请求,完成后应该缓存在服务器端。我的问题是 - 我不知道如何防止它在第一次请求后被缓存之前被调用 concurrently/simultaneously。
我的想法是我应该创建一个数据请求 Task
并将其存储在并发字典中。所以每个其他请求都应该检查 Task
是否已经 运行 并等待它完成。
我已经结束了:
private static ConcurrentDictionary<string, Task> tasksCache = new ConcurrentDictionary<string, Task>();
public static T GetFromCache<T>(this ICacheManager<object> cacheManager, string name, Func<T> func)
{
if (cacheManager.Exists(name))
return (T)cacheManager[name];
if (tasksCache.ContainsKey(name))
{
tasksCache[name].Wait();
return (tasksCache[name] as Task<T>).Result;
}
var runningTask = Task.Run(() => func.Invoke());
tasksCache[name] = runningTask;
runningTask.Wait();
var data = runningTask.Result;
cacheManager.Put(name, data);
tasksCache.TryRemove(name, out Task t);
return data;
}
但这看起来很乱。有没有更好的方法?
我会考虑将这些包装在每个任务的 Lazy<T>
中,它具有用于控制并发初始化的内置语义。
This example 演示了如何使用 Lazy<T>
class 来提供从多个线程访问的惰性初始化。
您需要指定合适的 LazyThreadSafetyMode
。
Fully thread safe; uses locking to ensure that only one thread initializes the value.
ExecutionAndPublication