У меня есть Потокобезопасная класс:Возможная неправильная реализация двойной проверки блокировки
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 дает мне три предупреждения:
- На гауссовой в
gaussian.ConformRepeatPadding()
он говорит возможна некорректная реализация Double - блокировка чеков. Прочитайте доступ к проверенному полю.. - На гауссовском языке в
gaussian = new PaddedImage(
говорится: Возможная некорректная реализация блокировки с двойной проверкой. Возможно множественный доступ на запись к отмеченному полю.. - На гауссовском языке в
ImageProcessing.CalcGaussian(image,gaussian,temp,
указано Возможная некорректная реализация блокировки с двойной проверкой. Прочитайте доступ к проверенному полю. (То же предупреждение, что и номер 1).
Могу ли я быть глупым или resharper?
PS: В случае, если я пропустил что-то важное, вот полный код класса с частями, которые я пропустил выше.
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: Вот скриншот в случае ситуация не ясна:
Это задокументировано [здесь] (https://www.jetbrains.com/help/resharper/2016.1/ReadAccessInDoubleCheckLocking.html) и [здесь] (https://www.jetbrains.com/help/resharper/2016.1 /PossibleMultipleWriteAccessInDoubleCheckLocking.html) – stuartd