【问题标题】:Synchronous hold of a specific code in an asynchronous method in c #c#中异步方法中特定代码的同步保持
【发布时间】:2021-03-02 18:08:44
【问题描述】:

注意:我使用了语言翻译

我在 C# 中使用的 api 系统中的一个方法中过滤并返回缓存的数据。如果缓存中没有数据,我会异步从数据库中拉取数据。如果缓存中没有数据,则同时来到 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());
    }
}

【问题讨论】:

    标签: c# asynchronous queue task-queue


    【解决方案1】:

    你需要的是一个队列,它会按顺序依次执行 InsertCacheForGetPersonels()。

    因为我注意到您已经在使用任务工厂,所以我建议您查看有关使用任务计划程序和任务工厂的 Microsoft 示例。

    https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskscheduler?view=net-5.0

    【讨论】:

      【解决方案2】:

      我查看了链接。我上过这样的课。是我错了吗?

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

      【讨论】:

      • ``` if (list is null) lock (QueueTasker.Instance().lockObj) QueueTasker.Instance().Add(() => InsertCacheForSelect(CacheControlType.Insert)); ```这样使用它就可以了
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-30
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多