Visual Studio C#和短路评估

时间:2017-06-20 09:39:05

标签: c# visual-studio

使用||运营商,Microsoft在此描述了短路评估Short Circuit Evaluation

但是,我有以下代码似乎与此过程相矛盾:

  if ((_opcLoaded || DoLoadOPC()) &&
     (_tagsAdded || DoAddTags()) &&
     DoWriteRecipe() && 
     (DoResume()))

我试图阻止的是如果_tagsAdded为真,则调用DoAddTags函数(DoAddTags将_tagsAdded设置为true)。

然而,即使DoAddTag为真,我也发现_tagsAdded被调用了。 _opcLoadedDoLoadOPC的情况相同。我必须在DoAddTags内添加一个条件来检查_tagsAdded,这不应该是必要的。

有人可以解释为什么会这样吗?

这是完整代码

    //
                        // Resume a Paused recipe
                    case MonitoredTasks.Resume:
                        Task.Factory.StartNew(() =>
                            {
                                MonitoredTask = MonitoredTasks.None;
                                if ((_opcLoaded || DoLoadOPC()) &&
                                      **(_tagsAdded || DoAddTags())** &&
                                      DoWriteRecipe() && 
                                      (DoResume()))
                                {
                                    MonitoredTask = MonitoredTasks.None;
                                    RunningState = RecipeRunningStates.Running;
                                    Status = CIPStatuses.Running;
                                }
                                else
                                {
                                    MonitoredTask = MonitoredTasks.Resume;
                                }
                            });

                        break;

DoAddTags的代码

        /// <summary>
    /// Adds all necessary tags to the OPC Server Manager
    /// </summary>
    /// <returns></returns>
    bool DoAddTags()
    {

        bool result = false;
        var oldActivity = Activity;
        //
        // Not doing anything OPC related?
        if (Activity != CIPActivities.AddingOPCTags && !_tagsAdded && Activity != CIPActivities.StartingOPC)
        {
            lock (_locks[LOCK_OPC])
            { 
                Activity = CIPActivities.AddingOPCTags;
                Status = CIPStatuses.Initialising;
                RecipeError = Errors.None;
                try
                {
                    //
                    // Reset connection and internal tags list
                    _serverManager.Reset();

                    //
                    // Now to add all OPC Tags - Area
                    CIPStatusTag = _serverManager.AddTag(_area.CIPStatusTag);
                    RecipeIDTag = _serverManager.AddTag(_area.RecipeIDTag);
                    RecipeInstructionIDTag = _serverManager.AddTag(_area.RecipeInstructionIDTag);
                    HandshakingTag = _serverManager.AddTag(_area.HandshakingTag);
                    GlobalInstructionIDTag = _serverManager.AddTag(_area.GlobalInstructionIDTag);
                    InstructionAttemptsTag = _serverManager.AddTag(_area.InstructionAttemptsTag);

                    //
                    // Area tags OK?
                    if (CIPStatusTag == null || RecipeIDTag == null || RecipeInstructionIDTag == null || HandshakingTag == null || GlobalInstructionIDTag == null || InstructionAttemptsTag == null)
                    {
                        RecipeError = Errors.InvalidAreaTags;
                        DoError(new RecipeErrorHandlerEventArgs(this) { Message = FormatMessage("CIPRecipe.DoAddTags - Invalid AREA Tags"), Sender = this });
                    }
                    else
                    {

                        VM_CIPInstruction vm = null;
                        bool instructionTagErrors = false;
                        //
                        // For each area instruction that is used, assig a link to the instruction
                        foreach (var i in _areaInstructions)
                        {
                            //
                            // Create a View Model for the specified area instruction : this allows us to determine the number of parameters (tags) that apply to the instruction
                            vm = new VM_CIPInstruction(i.Value.Instruction);
                            //
                            // Assign device reference tags
                            if (vm.DeviceReferencesAvailable)
                            {
                                i.Value.DeviceTag = _serverManager.AddTag(i.Value.Instruction.DeviceReferenceTag);
                                instructionTagErrors = i.Value.DeviceTag == null;
                            }
                            //
                            // For  each required parameter, add tag
                            for (int paramNo = 1; paramNo <= vm.NoOfParams; paramNo++)
                            {
                                switch (paramNo)
                                {
                                    case 1:
                                        //
                                        // Tag defined? Add it 
                                        if (vm.AreaInstruction.Param1Tag >= 0)
                                        {
                                            i.Value.Param1 = _serverManager.AddTag(i.Value.Instruction.Param1Tag);

                                            if (i.Value.Param1 == null)
                                            {
                                                instructionTagErrors = true;
                                            }
                                        }
                                        else
                                        {
                                            instructionTagErrors = true;
                                        }
                                        break;
                                    case 2:
                                        //
                                        // Tag defined? Add it 
                                        if (vm.AreaInstruction.Param2Tag >= 0)
                                        {
                                            i.Value.Param2 = _serverManager.AddTag(i.Value.Instruction.Param2Tag);

                                            if (i.Value.Param2 == null)
                                            {
                                                instructionTagErrors = true;
                                            }
                                        }
                                        else
                                        {
                                            instructionTagErrors = true;
                                        }
                                        break;
                                    case 3:
                                        //
                                        // Tag defined? Add it 
                                        if (vm.AreaInstruction.Param3Tag >= 0)
                                        {
                                            i.Value.Param3 = _serverManager.AddTag(i.Value.Instruction.Param3Tag);

                                            if (i.Value.Param3 == null)
                                            {
                                                instructionTagErrors = true;
                                            }
                                        }
                                        else
                                        {
                                            instructionTagErrors = true;
                                        }
                                        break;
                                    case 4:
                                        //
                                        // Tag defined? Add it and then check quality
                                        if (vm.AreaInstruction.Param4Tag >= 0)
                                        {
                                            i.Value.Param4 = _serverManager.AddTag(i.Value.Instruction.Param4Tag);

                                            if (i.Value.Param4 == null)
                                            {
                                                instructionTagErrors = true;
                                            }
                                        }
                                        else
                                        {
                                            instructionTagErrors = true;
                                        }
                                        break;

                                    case 5:
                                        //
                                        // Tag defined? Add it and then check quality
                                        if (vm.AreaInstruction.Param5Tag >= 0)
                                        {
                                            i.Value.Param5 = _serverManager.AddTag(i.Value.Instruction.Param5Tag);

                                            if (i.Value.Param5 == null)
                                            {
                                                instructionTagErrors = true;
                                            }
                                        }
                                        else
                                        {
                                            instructionTagErrors = true;
                                        }
                                        break;

                                    case 6:
                                        //
                                        // Tag defined? Add it and then check quality
                                        if (vm.AreaInstruction.Param6Tag >= 0)
                                        {
                                            i.Value.Param6 = _serverManager.AddTag(i.Value.Instruction.Param6Tag);

                                            if (i.Value.Param6 == null)
                                            {
                                                instructionTagErrors = true;
                                            }
                                        }
                                        else
                                        {
                                            instructionTagErrors = true;
                                        }
                                        break;
                                }
                            }

                            if (instructionTagErrors)
                            {
                                RecipeError = Errors.InvalidInstructionTags;
                                DoError(new RecipeErrorHandlerEventArgs(this) { Message = FormatMessage(String.Format("CIPRecipe.DoAddTags - Invalid Instruction {0} Tags", vm.Name)), Sender = this });
                                break;
                            }
                        }
                        //
                        // Any problems adding tags?
                        if (RecipeError == Errors.None)
                        {
                            Activity = CIPActivities.StartingOPC;
                            //
                            // Once all tags added, start OPC Server
                            result = _serverManager.Start();

                            if (!result)
                            {
                                Status = CIPStatuses.AddTagsFailed;
                                RecipeError = Errors.OPC;
                                DoError(new RecipeErrorHandlerEventArgs(this) { Message = FormatMessage("CIPRecipe.DoAddTags - Start of OPC failed"), Sender = this });
                            }
                            else
                            {
                                **_tagsAdded = true;**
                                Status = CIPStatuses.TagsAdded;
                            }
                        }
                        else
                        {
                            Status = CIPStatuses.AddTagsFailed;
                        }
                    }
                }
                catch (Exception ex)
                {
                    RecipeError = Errors.Exception_AddTags;
                    DoError(new RecipeErrorHandlerEventArgs(this) { Message = FormatMessage("CIPRecipe.DoAddTags"), Exception = ex, Sender = this });
                }
                finally
                {
                    Activity = oldActivity;
                }
            }
        }
        return Status == CIPStatuses.TagsAdded;
    }

我用**

突出显示了相关的行

在第一次执行时,执行DoAddTags并将_tagsAdded设置为TRUE-我在这里放置了一个断点,所以我知道它正在被设置。不久之后(有或没有前断点)再次输入DoAddTags(在第一行),尽管_doAddTags == true。

我甚至在代码上设置了断点&#34; (_ tagsAdded || DoAddTags())&#34;。 _tagsAdded == true,但仍然输入了DoAddTags。

所以我所看到的是,并且所有的手表/调试信息都与之一致是在调用DoAddTags而_tagsAdded == true

1 个答案:

答案 0 :(得分:2)

此代码不会显示您描述的行为,短路的工作原理如上所述。

实际发生的事情:_tagsAdded最初为false,因此调用了DoAddTags(),将_tagsAdded设置为true

然后调试器启动,您检查_tagsAdded并看到它是true

而是使用F11逐步执行代码并检查或观察所有相关变量。