3

なぜ .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);

多くの場合、値の型をスレッドの開始に渡すと、ボックス化/ボックス化解除を行う必要があるためです。

4

6 に答える 6

4

BCL を実装している人々がわざわざ次のようなものを書かなかった理由がいくつかわかります。

  1. パフォーマンスが心配な場合は、キャスト (ボックス化解除であっても) は、実際にスレッドを作成するよりもはるかに小さなヒットになります。
  2. 型の安全性が心配な場合は、簡単に lambda: を使用できますnew Thread(() => SayHello("Hello"))
  3. Thread<T>T何を表しているのか明確でないため、紛らわしいタイプです。特に、 とはまったく異なる意味を持つためTですTask<T>
  4. 必要に応じて、20 行を使用してラッパーとして作成できますThread<T>(以下を参照)。

したがって、問題が実際に気になり、解決策が混乱する可能性がある場合、問題は小さく、簡単に回避できます. これが、これを実装するためにリソースが費やされなかった理由である可能性が最も高いです。


可能な実装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);
    }
}
于 2013-01-28T12:07:39.087 に答える
2

ラムダを使用してスレッドを開始して強い型付けを使用するのは非常に簡単なので、新しい言語サポートを追加する必要はありません。

例えば:

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);
    }
}
于 2013-01-28T12:43:07.317 に答える
2

誰もそのメソッドをまだ書いていないからです。さらに、ここでのボックス化/ボックス化解除は操作全体のかなり小さな部分であり、実際にスレッドを手動で開始する必要があるプログラマーはほとんどいないため (ほとんどのユースケースにはより良い抽象化があります)、おそらく指定、実装、テスト、文書化の必要性をほとんど感じませんでした。基本的に不要な変更。

于 2013-01-28T11:52:13.087 に答える
1

ジェネリックの導入後に設計された場合、ジェネリックバージョンがあると思われる.netには多くのクラスがあります。スレッドはその 1 つにすぎません。

この特定の問題について、.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を改善し続ける可能性があります。

于 2013-01-28T11:52:15.473 に答える
0

「歴史的理由」によるものです。そのメソッドは .NET 1 (ジェネリックなし) で作成され、その後修正されませんでした。ICloneable などと同じです。

于 2013-01-28T11:51:32.177 に答える
0

奇妙な.. OPが求めていることをなぜ誰かがやりたいのか、実際には誰も尋ねませんでした。スレッドは、コードを実行するように設計されています。スレッドはメソッドではありません。.NET のジェネリックの性質から、コード new Thread() は、特定の型 (文字列) を持つオブジェクトの作成を意味します。これは、しばらくの間実行して何かを行うという Thread クラスの目的とはまったく関係ありません。複雑なもの。

私の考えを説明するために-これは彼が尋ねたのと同じです-テレビとXBOXを備えたスチームローラーを持っていないのはなぜですか.

つまり、.NET のアーキテクチャと矛盾するため、これは実装されていません

于 2013-01-31T04:38:14.407 に答える