比较线程是否相等

时间:2012-03-28 17:23:35

标签: c# .net multithreading coding-style

我正在寻找一种方法来解释通过调用ReferenceEquals()来使用高级业务逻辑是不合理的。

这是一个我遇到问题的代码片段(方法中的前置条件,如果我们在一个错误的线程上就会抛出):

if (!object.ReferenceEquals(Thread.CurrentThread, RequestHandlerThread))

写这个是否可靠:

if (Thread.CurrentThread != RequestHandlerThread)

我建议在比较中使用ManagedThreadIds,这是基于我在教程中常见的内容。对手说参考平等的比较看起来更像是面向对象。

这是(大致)我在Reflector的.NET 4.0 System.Object视图中看到的内容。请记住,Thread类是密封的,并且对于operator ==。

没有重载
public static bool ReferenceEquals(object objA, object objB)
{
    return (objA == objB);
}

public static bool Equals(object objA, object objB)
{
    return (objA == objB || 
        (objA != null && objB != null && objA.Equals(objB)));
}

以下是一些基本测试,验证线程池上的操作......我是否错过了任何重要的测试?

using System.Threading;
using System.Diagnostics;
using System.Threading.Tasks;

namespace ConsoleApplicationX
{
   class Program
   {
      static readonly Thread mainThread;

      static Program()
      {
         mainThread = Thread.CurrentThread;
      }

      static void Main(string[] args)
      {
         Thread thread = Thread.CurrentThread;
         if (thread != Thread.CurrentThread)
            Debug.Fail("");

         if(Thread.CurrentThread != thread)
            Debug.Fail("");

         if (thread != mainThread)
            Debug.Fail("");

         var task = Task.Factory.StartNew(() => RunOnBackground(thread));
         task.Wait();

         var anotherThread = new Thread(new ParameterizedThreadStart(RunInAnotherThread));
         anotherThread.Start(thread);
      }

      static void RunOnBackground(Thread fromInitial)
      {
         if (Thread.CurrentThread == fromInitial)
            Debug.Fail("");

         if (fromInitial != mainThread)
            Debug.Fail("");
      }

      static void RunInAnotherThread(object fromInitialAsObject)
      {
         var fromInitial = (Thread)fromInitialAsObject;

         if (Thread.CurrentThread == fromInitial)
            Debug.Fail("");

         if (fromInitial != mainThread)
            Debug.Fail("");
      }
   }
}

4 个答案:

答案 0 :(得分:7)

尽量不要讲道,但...... 通常,如果要使用标识属性,在这种情况下

Thread.ManagedThreadId

它应该用于相等比较,除非执行代码存在性能约束。指针比较的语义与等式有很大不同。此外,指针比较取决于mscorlib中Thread的实现。

答案 1 :(得分:2)

你是对的。正如您的反思查询所示,这两种方式是等价的(除非以对手的方式进行额外的方法调用)

答案 2 :(得分:1)

我可以看到一个实现如何使用两个不同的引用,但仍然会在内部指向同一个线程。假设参考平等意味着威胁相等,这是可以的。但这并不意味着如果它们不同,那么对象在语义上就不相等。仅这一点就足以反对在业务逻辑中比较引用的做法。

答案 3 :(得分:0)

简短回答:

使用ManagedThreadId属性进行比较。

简单示例:

想象一下,我们有一个名为StackOverflow.MessageThread的类。程序员胖手指一个函数的前提条件,说Debug.Assert(Thread.CurrentThread == messageThread)。前提条件在运行时失败。如果dev会达到ManagedThreadId,他会在编辑时发现它是不可能的,并且会在开发周期的早期解决问题。