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;
        }
    }