Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 双重检查锁定的可能错误实现_C#_Multithreading - Fatal编程技术网

C# 双重检查锁定的可能错误实现

C# 双重检查锁定的可能错误实现,c#,multithreading,C#,Multithreading,我有一个线程安全类: 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

我有一个线程安全类:

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上的
    gaussian.com()
    中指出可能不正确地实现了双重检查锁定。对选中字段的读取权限。
  • 在gaussian上,在
    gaussian=new PaddedImage(
    它表示可能不正确地执行了双重检查锁定。可能对选中字段进行了多次写入访问。
  • 在图像处理.CalcGaussian(图像,高斯,温度,中的gaussian)上,它表示可能不正确地执行了双重检查锁定。读取对选中字段的访问。(与数字1相同的警告)
  • 我是傻了还是雷沙珀傻了

    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();
        }
      }
    }
    
    使用系统;
    使用System.IO;
    使用系统文本;
    命名空间UPlus.TerrEngine
    {
    内部类ExmplFile:IEquatable
    {
    私有只读字符串文件名;
    私有整数分解;
    私有图像;
    私有易失性paddiedimage高斯;
    私有对象lockObject=新对象();
    公共ExmplFile(字符串抽象文件名,int-res)
    {
    filename=新的StringBuilder(abstractFileName).Append(“-”).Append(res.ToString(“D4”)).ToString();
    分辨率=分辨率;
    }
    内部填充列表[]GetMatchItems(int-groupIdx,int-regionIdx)
    {
    AlgorithmConfig Config=TerraGodContext.Instance().Config;
    if(resolution!=Config.ExmplResDS)抛出新异常();
    PpaGraph exmplGraph=新的PpaGraph(Config.ExmplResDS,Config.ExmplResDS,Config.ExmplResDS
    /Config.ppaexplresds);
    计算(Image(),true,false,DebugOpts.BranchMin);
    PrepareGraphForMatch(Config.ExmplCptRadius,Config.exmplprocNodeInstance);
    exmplGraph.CalcExmplProcNodeGroups(groupIdx);
    MatchItemFinder MatchItemFinder=新的MatchItemFinder(Image(),Config.ExmplPatchSizeDS,true);
    matchItemFinder.Init(exmplGraph.processNodesGroups,regionIdx);
    返回matchItemFinder.matchItems;
    }
    内部FastList LoadMatchItems()
    {
    抛出新异常();
    }
    内部PaddeImage图像()
    {
    如果(图像!=null)
    {
    返回图像;
    }
    锁定(锁定对象)
    {
    if(image==null)
    {
    image=LoadImage(文件名+“.raw”,TerraGodContext.Instance().Config
    (b)特兰奇(e);;
    }
    }
    返回图像;
    }
    内部填充图像高斯()
    {
    if(高斯!=null)
    {
    返回高斯分布;
    }
    锁定(锁定对象)
    {
    如果(高斯==null)
    {
    图像();
    如果(File.Exists(filename+“-gaus.raw”))
    {
    gaussian=LoadImage(文件名+“-gauss.raw”,TerraGodContext.Instance()
    .Config.ppatarange);
    gaussian.padding();
    }
    其他的
    {
    高斯=新的填充图像(分辨率、分辨率、假、,
    TerraGodContext.Instance().Config.PpaCandidateRange);
    PaddedImage temp=新的PaddedImage(分辨率、分辨率、假、,
    TerraGodContext.Instance().Config.PpaCandidateRange);
    图像处理.CalcGaussian(图像,高斯,温度,16f*分辨率
    /TerraGodContext.Instance().Config.ExmplResDS);
    }
    }
    }
    返回高斯分布;
    }
    私有PaddedImage LoadImage(字符串文件名,整数填充)
    {
    PaddedImage img=新的PaddedImage(分辨率、分辨率、假、填充);
    LoadRaw(文件名);
    img.padding();
    返回img;
    }
    公共布尔等于(ExmplFile其他)
    {
    返回filename==other.filename;
    }
    公共覆盖int GetHashCode()
    {
    返回filename.GetHashCode();
    }
    }
    }
    
    编辑:如果情况不清楚,这里有一个屏幕截图:


    尝试使用来定义您的属性。您的代码看起来正确,但这应该可以消除错误,这是一种适用于此类事情的框架模式

    尝试使用来定义您的属性。您的代码看起来正确,但应该可以消除错误,并且是适用于此类事情的框架模式

    T你的锁有点奇怪。我在静态锁对象而不是私有对象上见过它。
    如果你的类不是singleton,那么你的锁就会通过,因为没有锁。

    你的锁有点奇怪。我在静态锁对象而不是私有对象上见过它。
    如果您的类不是单例的,那么您的锁将通过,因为没有锁。

    通常,在
    锁中,您应该使用局部变量,并将对选中字段的写入作为最后一个可能的操作

    另外,你在中间做什么?例如<代码>构象重复pAdvices()/代码>?我猜它有副作用,因为它没有返回值。但是在你调用它的时候,你已经通过将它的值分配给该字段来暴露该对象。


    其他线程可能能够以“部分构造”的方式观察此对象说明如果过早分配给字段,如我所说,通常应使写入字段成为
    锁中最后一个可能的操作
    通常,在
    锁中,应使用局部变量并使写入选中字段成为最后一个可能的操作

    另外,你在中间做什么?例如<代码>构象重复pAdv>代码>?我猜它是有边的。