2

我需要使用锁(createPaletteLocker)吗?我正在使用它,因为我认为这样做可以避免在其他线程正在读取它时写入 ColorPaletteHandle.palettesList[type]。

编辑 1:字典仅在静态构造函数中设置。因此,我将不再更改(添加/删除),但它所持有的立场将从 null 更改为相应创建的调色板。

public static class ColorPaletteHandle
{
    private static readonly object createPaletteLocker = new object();
    private static Dictionary<ColorPaletteType, ColorPalette> palettesList = null;

    static ColorPaletteHandle()
    {
        palettesList = new Dictionary<ColorPaletteType, ColorPalette>();
        palettesList.Add(ColorPaletteType.Default, ColorPaletteHandle.defaultPalette);
        palettesList.Add(ColorPaletteType.EdgesHighlight, ColorPaletteHandle.edgesHighlight);
        palettesList.Add(ColorPaletteType.GrayScale, ColorPaletteHandle.grayScale);
        palettesList.Add(ColorPaletteType.HeatMap, ColorPaletteHandle.heatMap);
    }

    /// <summary>
    /// Gets a palette.
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static ColorPalette GetPalette(ColorPaletteType type)
    {
        ColorPalette pal = null;
        lock (ColorPaletteHandle.createPaletteLocker)
        {
            pal = ColorPaletteHandle.palettesList[type];
            if (pal == null)
            {
                ColorPaletteHandle.palettesList[type] = ColorPaletteHandle.CreatePalette(type);
                pal = ColorPaletteHandle.palettesList[type];
            }
        }
        return pal;
    }

   //stuff...
   }
4

2 回答 2

6

该类Dictionary并非旨在从多个线程访问。除非您同步访问,否则这样做确实会导致问题。有了lock语句,方法就可以了,没有它就不行。

比使用更好的lock是使用 aConcurrentDictionary代替。它是专门设计用于同时从多个线程中使用的字典。您可以将整个方法重构为一次调用GetOrAdd.

于 2013-06-03T21:01:44.803 回答
2

是的,这种方法是线程安全的,因为一次只能修改一个线程palettesList,是的,如果你打算使用,你确实需要锁Dictionary

但是,如果您使用的是 .NET 4 或更高版本,ConcurrentDictionary会更适合这个

于 2013-06-03T21:02:15.303 回答