2

在我目前的项目中,我正在使用Boo / Rhino DSL(顺便说一句,这是一件多么棒的事情)。

在挖掘代码时,我遇到了以下代码:

engine.Cache.WriteLock( () =>
{
    engine.Storage.NotifyOnChange(urls, delegate(string invalidatedUrl)
    {
         engine.Cache.Remove(invalidatedUrl);
         if (!standAloneCompilation.Contains(invalidatedUrl))
             standAloneCompilation.Add(invalidatedUrl);
    });
});

这里的意图很清楚:engine.Cache当一个 url 被从中删除时,必须保护它免受竞争条件的影响。我在这里看到的问题是,真正受到保护的是调用Storage.NotifyOnChange- 而不是Cache.Remove.

所做NotifyOnChange的只是获取提供的委托并将其作为事件处理程序附加到它创建的“FileWatcher”。因此,这里不是保护Cache.Remove写锁,而是保护创建 FileWatcher,而不是Cache.Remove保护未受保护的。

我对 Boo 和 Rhino 都非常尊重,这让我想知道——这里有什么遗漏吗?或者写锁应该真的在委托内部移动?

如果您想知道,这里是 NotifyOnChange 代码:

    public virtual void NotifyOnChange(IEnumerable<string> urls, Action<string> action)
    {
        lock (pathToFileWatchers)
        {
            string[] commonPaths = GatherCommonPaths(urls);
            foreach (string path in commonPaths)
            {
                FileSystemWatcher watcher;
                if(pathToFileWatchers.TryGetValue(path, out watcher)==false)
                {
                    pathToFileWatchers[path] = watcher = new FileSystemWatcher(path, FileNameFormat);
                    watcher.EnableRaisingEvents = true;
                }
                watcher.Changed += delegate(object sender, FileSystemEventArgs e)
                {
                    action(e.FullPath);
                };
            }
        }
    }
4

0 回答 0