代码理解问题

时间:2011-03-02 13:11:42

标签: c#

今天早上,当我遇到一个我不理解的C#代码示例时,我正在阅读源代码:

public bool Dequeue(out T value)
{
    Node head;
    Node tail;
    Node next;

    while (true)
    {
        // read head
        head = this.head;
        tail = this.tail;
        next = head.Next;

        // Are head, tail, and next consistent?
        if (Object.ReferenceEquals(this.head, head))
        {
           // Source code continues here...
        }
        // And here...
    }
}

我遇到的问题是包含Object.ReferenceEquals()的问题。

如果我理解得很好,源代码作者想要比较this.headhead,但在上面的行中,他只是写了head = this.head

主要来自C++背景,这句话对我来说毫无意义。此外,在某些情况下,似乎Object.ReferenceEquals()行会抛出一个System.NullReferenceException所以它确实会有所作为,我无法弄清楚是什么。

你能帮助我理解这条线路的作用以及可能的原因吗?

如果你需要这个,这里是Node类定义(我猜它是一个“模板”类,不确定C#的措辞):

private class Node
{
    public T Value;
    public Node Next;

    public Node(T value)
    {
        this.Value = value;
    }
}

谢谢。

编辑:方法的其余部分,对于那些要求

的人
    public void Enqueue(T value)
    {
        // Allocate a new node from the free list
        Node valueNode = new Node(value);

        while (true)
        {
            Node tail = this.tail;
            Node next = tail.Next;

            // are tail and next consistent
            if (Object.ReferenceEquals(tail, this.tail))
            {
                // was tail pointing to the last node?
                if (Object.ReferenceEquals(next, null))
                {
                    if (Object.ReferenceEquals(
                            Interlocked.CompareExchange(ref tail.Next, valueNode, next),
                            next
                            )
                        )
                    {
                        Interlocked.CompareExchange(ref this.tail, valueNode, tail);
                        break;
                    }
                }
                else // tail was not pointing to last node
                {
                    // try to swing Tail to the next node
                    Interlocked.CompareExchange<Node>(ref this.tail, next, tail);
                }
            }
        }
    }

5 个答案:

答案 0 :(得分:2)

看起来像一个链表。 Dequeue看起来像一个递归函数。 因此,“Next”会对节点的“head”部分执行某些操作,或者它并行运行,并且在继续操作之前,他会尝试检查内容是否仍然存在。最后一部分操作不正确,因为您在进入临界区时应该使用信号量,否则您将遇到竞争条件并且迟早会失败。

答案 1 :(得分:1)

如果this.headthis.tail是公开的,则可以在循环运行时更改它们。 Object.ReferenceEquals检查它们是否与执行方法时相同。

如果没有全班/上下文,很难给出更完整的答案。

答案 2 :(得分:1)

  

他刚写了head = this.head

这是作业,并且与比较它们有关。请注意,这是关于字段head和本地var this.head

  

if(Object.ReferenceEquals(this.head,head))

此处作者希望比较this.headhead,同时确保相等性基于其引用(地址),而不是==和{{{} {{}} 1}}

我假设在循环内部正在更改局部变量Equals(),这使它成为一个有争议的命名。

答案 3 :(得分:1)

ReferenceEquals是一个函数,用于确保对象的两个实例是完全相同的对象,而不仅仅是两个具有相同值的对象。可以在此处找到文档(http://msdn.microsoft.com/en-us/library/system.object.referenceequals.aspx)。至于该语句的目标,如果这个代码在多线程上下文中执行,他可能会试图确保没有人因为他做了(非常危险),或者担心有人传入值类型(危险) ,但更好的检查方法)。

编辑:随着更多代码发布,它看起来像第一件事。当有多个线程时,他正在使用ReferenceEquals来尝试捕捉他的竞争条件(如果它不是多线程的,他就不会打扰InterlockedExchange)。代码似乎基本上是在尝试执行操作,并且,如果有人在中途改变了马匹,只需再次尝试(而(真实))。使用关键部分或信号量来确保没有人修改你的价值观,而不是简单地希望你能检查它们是否有所改变,这可能更为优雅。原因是 AFTER IF,但 BEFORE InterlockedExchange,有人可能会修改您的值,这会引入错误。

答案 4 :(得分:1)

Interlocked.CompareExchange方法用于执行线程安全比较和替换 - 这意味着此方法应该能够处理外部线程修改队列的情况。 if语句正在尝试处理列表已被其他线程修改的情况