简体   繁体   English

运行任务时访问 ConcurrentDictionary 元素

[英]Accessing ConcurrentDictionary element while running Task

The given code attempts to run a fire-and-forget Task while acquiring a lock to avoid race conditions on a cached element.给定的代码尝试在获取锁的同时运行即发即弃Task ,以避免缓存元素出现竞争条件。 while debugging the whole application I noticed bizarre behavior - getting to the same break point with the same key.在调试整个应用程序时,我注意到奇怪的行为 - 使用相同的键到达相同的断点。 That said, I'm not sure if the assumption that ConcurrentDictionary guarantees that only one writer will be applied to the element as well as locking inside the Task.Run block will assure me that this and only this Task will have access to the element itself.也就是说,我不确定ConcurrentDictionary保证只有一个编写器将应用于该元素以及锁定在Task.Run块内的假设是否会向我保证只有这个任务才能访问元素本身.

    Task.Run(() =>
    {
        lock (GetLockContext(key, region))
        {
            try
            {
                object newValue = cacheInterceptor.Intercept<T>(ctx);
                Put(refreshContext.Key, newValue, refreshContext.Region, refreshAction);
            }
            catch (Exception ex)
            {
                refreshContext.UpdteRefreshNeeded(true);
                LogError("HANDLE_REFRESH", null, null, ex);
            }
        });
    }
        private object GetLockContext(string key, string region)
        {
            string ctx = key + region;
            object lckCtx = CTX_REPO.GetOrAdd(ctx, (dontcare) => new object());

            return lckCtx;
        }
private static readonly ConcurrentDictionary<string, object> CTX_REPO

The lock (GetLockContext(key, region)) should guarantee that only one thread in the current process will enter the critical region for the same key/region combination. lock (GetLockContext(key, region))应该保证当前进程中只有一个线程会进入同一键/区域组合的临界区。 The only problems that I can think of are:我能想到的唯一问题是:

  1. The key + region generates the same combination for different key/region pairs. key + region为不同的键/区域对生成相同的组合。 For example "ab" + "c" and "a" + "bc" .例如"ab" + "c""a" + "bc"
  2. Your application is hosted, and the host starts a new process before the currently running process has terminated.您的应用程序已托管,并且主机在当前运行的进程终止之前启动了一个新进程。

As a side note instead of locking synchronously you could consider using an asynchronous locker like the SemaphoreSlim class, in order to avoid blocking ThreadPool threads.作为旁注而不是同步锁定,您可以考虑使用像SemaphoreSlim class 这样的异步锁柜,以避免阻塞ThreadPool线程。 You could check out this question for ideas: Asynchronous locking based on a key .您可以查看此问题以获取想法: Asynchronous locking based on a key

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM