c#中异步方法中特定代码的同步保持
Synchronous hold of a specific code in an asynchronous method in c #
注意:我使用了语言翻译
我在C#中使用的api系统中的一个方法中过滤和return缓存数据。如果缓存中没有数据,我会异步从数据库中拉取它。如果缓存中没有数据,则同时进入 api 的投标人会在异步代码中相互挤压。所以第一个请求者必须第一个拉取数据,其他人应该等待第一个请求者拉取数据。我写的代码:
[HttpPost]
public ... GetPersonels(...)
{
var list = caching.Get<...>([CacheName]);
if (list is null)
{
System.Threading.Tasks.Task.Factory.StartNew(InsertCacheForGetPersonels);
}
...
return [Filtred Personels];
}
protected void InsertCacheForGetPersonels()
{
//HERE !!!
//what should i do here ?
//HERE !!!
if (caching.Get<...>([CacheName]) is null)
{
var list = GetPersonelList();
caching.Set(list, [CacheName], Indefinite());
}
}
您需要的是一个队列,它将一个接一个地执行 InsertCacheForGetPersonels() 以便他们进入。
因为我注意到您已经在使用 Task Factory,所以我建议您查看这个有关使用 Task Scheduler 和 Task Factory 的 Microsoft 示例。
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskscheduler?view=net-5.0
我看了link。我做了这样一个class。我说错了吗?
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskscheduler?view=net-5.0
public class QueueTasker
{
public LimitedConcurrencyLevelTaskScheduler lcts;
public List<Task> tasks;
public TaskFactory factory;
public CancellationTokenSource cts;
public object lockObj;
private static QueueTasker _instance;
private QueueTasker()
{
lcts = new LimitedConcurrencyLevelTaskScheduler(1);
tasks = new List<Task>();
factory = new TaskFactory(lcts);
cts = new CancellationTokenSource();
lockObj = new object();
}
public static QueueTasker Instance()
{
if (_instance is null)
_instance = new QueueTasker();
return _instance;
}
public Task Add(Action action)
{
var task = factory.StartNew(action, cts.Token);
tasks.Add(task);
return task;
}
}
注意:我使用了语言翻译
我在C#中使用的api系统中的一个方法中过滤和return缓存数据。如果缓存中没有数据,我会异步从数据库中拉取它。如果缓存中没有数据,则同时进入 api 的投标人会在异步代码中相互挤压。所以第一个请求者必须第一个拉取数据,其他人应该等待第一个请求者拉取数据。我写的代码:
[HttpPost]
public ... GetPersonels(...)
{
var list = caching.Get<...>([CacheName]);
if (list is null)
{
System.Threading.Tasks.Task.Factory.StartNew(InsertCacheForGetPersonels);
}
...
return [Filtred Personels];
}
protected void InsertCacheForGetPersonels()
{
//HERE !!!
//what should i do here ?
//HERE !!!
if (caching.Get<...>([CacheName]) is null)
{
var list = GetPersonelList();
caching.Set(list, [CacheName], Indefinite());
}
}
您需要的是一个队列,它将一个接一个地执行 InsertCacheForGetPersonels() 以便他们进入。
因为我注意到您已经在使用 Task Factory,所以我建议您查看这个有关使用 Task Scheduler 和 Task Factory 的 Microsoft 示例。
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskscheduler?view=net-5.0
我看了link。我做了这样一个class。我说错了吗?
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskscheduler?view=net-5.0
public class QueueTasker
{
public LimitedConcurrencyLevelTaskScheduler lcts;
public List<Task> tasks;
public TaskFactory factory;
public CancellationTokenSource cts;
public object lockObj;
private static QueueTasker _instance;
private QueueTasker()
{
lcts = new LimitedConcurrencyLevelTaskScheduler(1);
tasks = new List<Task>();
factory = new TaskFactory(lcts);
cts = new CancellationTokenSource();
lockObj = new object();
}
public static QueueTasker Instance()
{
if (_instance is null)
_instance = new QueueTasker();
return _instance;
}
public Task Add(Action action)
{
var task = factory.StartNew(action, cts.Token);
tasks.Add(task);
return task;
}
}