I have a thread safe class:
internal class ExmplFile { private readonly string filename; private int resolution; private volatile PaddedImage gaussian; private object lockObject=new object(); //blah, blah, blah internal PaddedImage Gaussian() { if (gaussian != null) { return gaussian; } lock (lockObject) { if (gaussian == null) { Image(); if (File.Exists(filename + "-gaus.raw")) { gaussian = LoadImage(filename + "-gaus.raw", TerraGodContext.Instance() .Config.PpaCandidateRange); gaussian.ConformRepeatPadding(); } else { gaussian = new PaddedImage(resolution, resolution, false, TerraGodContext.Instance().Config.PpaCandidateRange); PaddedImage temp = new PaddedImage(resolution, resolution, false, TerraGodContext.Instance().Config.PpaCandidateRange); ImageProcessing.CalcGaussian(image,gaussian,temp, 16f* resolution /TerraGodContext.Instance().Config.ExmplResDS); } } } return gaussian; } } Resharper gives me three warnings:
- On gaussian in
gaussian.ConformRepeatPadding()it says Possible incorrect implementation of Double-check locking. Read access to checked field.. - On gaussian in
gaussian = new PaddedImage(it says Possible incorrect implementation of Double-check locking. Possible multiple write access to checked field.. - On gaussian in
ImageProcessing.CalcGaussian(image,gaussian,temp,it says Possible incorrect implementation of Double-check locking. Read access to checked field. (The same warning as number 1).
Am I being silly or Resharper is?
PS: In case I've missed something important, here is the full class code with parts I omitted above.
using System; using System.IO; using System.Text; namespace UPlus.TerrEngine { internal class ExmplFile : IEquatable<ExmplFile> { private readonly string filename; private int resolution; private volatile PaddedImage image; private volatile PaddedImage gaussian; private object lockObject=new object(); public ExmplFile(string abstractFileName, int res) { filename = new StringBuilder(abstractFileName).Append("-").Append(res.ToString("D4")).ToString(); resolution = res; } internal FilledList<MatchItem>[] GetMatchItems(int groupIdx, int regionIdx) { AlgorithmConfig Config = TerraGodContext.Instance().Config; if (resolution !=Config.ExmplResDS) throw new Exception(); PpaGraph exmplGraph = new PpaGraph(Config.ExmplResDS, Config.ExmplResDS, Config.ExmplResDS / Config.PpaExmplResDS); exmplGraph.Calculate(Image(), true, false, DebugOpts.BranchMin); exmplGraph.PrepareGraphForMatch(Config.ExmplCptRadius, Config.ExmplProcNodeDistance); exmplGraph.CalcExmplProcNodeGroups(groupIdx); MatchItemFinder matchItemFinder=new MatchItemFinder(Image(),Config.ExmplPatchSizeDS,true); matchItemFinder.Init(exmplGraph.processNodesGroups, regionIdx); return matchItemFinder.matchItems; } internal FastList<MatchItem> LoadMatchItems() { throw new Exception(); } internal PaddedImage Image() { if (image != null) { return image; } lock (lockObject) { if (image == null) { image=LoadImage(filename + ".raw", TerraGodContext.Instance().Config .PpaCandidateRange); } } return image; } internal PaddedImage Gaussian() { if (gaussian != null) { return gaussian; } lock (lockObject) { if (gaussian == null) { Image(); if (File.Exists(filename + "-gaus.raw")) { gaussian = LoadImage(filename + "-gaus.raw", TerraGodContext.Instance() .Config.PpaCandidateRange); gaussian.ConformRepeatPadding(); } else { gaussian = new PaddedImage(resolution, resolution, false, TerraGodContext.Instance().Config.PpaCandidateRange); PaddedImage temp = new PaddedImage(resolution, resolution, false, TerraGodContext.Instance().Config.PpaCandidateRange); ImageProcessing.CalcGaussian(image,gaussian,temp, 16f* resolution /TerraGodContext.Instance().Config.ExmplResDS); } } } return gaussian; } private PaddedImage LoadImage(string fileName, int padding) { PaddedImage img=new PaddedImage(resolution,resolution,false,padding); img.LoadRaw(fileName); img.ConformRepeatPadding(); return img; } public bool Equals(ExmplFile other) { return filename == other.filename; } public override int GetHashCode() { return filename.GetHashCode(); } } } EDIT: Here is a screenshot in case the situation is not clear:
