为什么.Net没有Thread.Start()的通用版本?

时间:2013-01-28 11:49:42

标签: c# multithreading

我想知道为什么.Net没有启动线程的通用方法。

例如,我们开始像以下一样的线程......

Thread th = new Thread(SayHello);
th.Start("Hello");

private static void SayHello(object obj)
        {
            string str = obj as string;
            Console.WriteLine(str);
        }

为什么我们不能理解为什么.Net团队不考虑将其变为通用?

喜欢跟随......

Thread<string> th = new Thread<string>(SayHello);

因为很多次我将值类型传递给线程启动时我必须进行装箱/拆箱。

6 个答案:

答案 0 :(得分:4)

我可以看到为什么实施BCL的人不打算写这样的东西的几个原因:

  1. 如果你担心性能,那么演员阵容(即使它是拆箱)将比实际创建线程小得多。
  2. 如果您担心类型安全,可以轻松使用lambda:new Thread(() => SayHello("Hello"))
  3. Thread<T>会是一个令人困惑的类型,因为它不清楚T代表什么。特别是因为它与T中的Task<T>具有完全不同的含义。
  4. 如果需要,可以使用20行(见下文)创建Thread<T>作为包装。
  5. 因此,如果它实际上困扰你并且解决方案可能令人困惑,那么这个问题很小且易于解决。这很可能是因为资源没有用于实现这一目标。


    可能实施Thread<T>

    class Thread<T>
    {
        private readonly Action<T> m_action;
        private readonly Thread m_thread;
        private T m_parameter;
    
        public Thread(Action<T> action)
        {
            m_action = action;
            m_thread = new Thread(DoWork);
        }
    
        public void Start(T parameter)
        {
            m_parameter = parameter;
            m_thread.Start();
        }
    
        private void DoWork()
        {
            m_action(m_parameter);
        }
    }
    

答案 1 :(得分:2)

因为还没有人写过那种方法。此外,由于这里的装箱/拆箱只占整个操作的一小部分很少有程序员实际上需要手动启动一个线程(大多数用例都有更好的抽象)他们可能认为没有必要指定,实施,测试和记录基本上不需要的变更。

答案 2 :(得分:2)

使用lambda启动一个线程很容易使用强类型,所以他们不需要为它添加任何新的语言支持。

例如:

using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        // Easy way to start a thread with strongly-typed multiple parameters:

        new Thread(() => MyThreadFunc("Test", 42, DateTime.Now)).Start();

        Console.WriteLine("Started thread.");
        Thread.Sleep(2000);
    }

    static void MyThreadFunc(string param1, int param2, DateTime param3)
    {
        Thread.Sleep(1000);
        Console.WriteLine("param1 = {0}, param2 = {1}, param3 = {2}", param1, param2, param3);
    }
}

答案 3 :(得分:1)

.net中有很多类,如果它们是在引入泛型后设计的,我想它会有一个通用版本。线程只是其中之一。

对于此特定问题,如果您可以使用.net 4.0 +:

使用System.Threading.Tasks命名空间中的Task类。

private static void SayHello(string s)
{
    Task t = new Task(() => Console.WriteLine(s));
    t.Start();
}

此示例是类型安全的,并按照您的示例执行操作。方法是不同的,如果你期待一个结果,任务确实更有意义,但仍然是一个很好的替代品,我想即使在这里。我的猜测是,MS不会将工作放在“旧的”Thread类中,但可能会继续改进Task Parallel Library

答案 4 :(得分:0)

由于“历史原因”。该方法是在.NET 1(没有泛型)中创建的,之后没有修复。与ICloneable等相同

答案 5 :(得分:0)

很奇怪..没有人真正问过为什么有人想要做OP所要求的。线程旨在运行一段代码。线程不是方法。从.NET中泛型的本质来看,代码新的Thread()意味着创建一个具有特定类型的对象 - 字符串。这无论如何与Thread类运行一段时间并做一些事情的目的有关。复杂的东西。

说明我的想法 - 就像他问的那样 - 为什么我们没有配备电视机和XBOX的压路机......

所以我所有的答案 - 这都没有实现,因为它与.NET的体系结构相矛盾。即* 错误 *而不是因为他们没有打扰。