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