Тема против Threadstart

В С#, практически, я не заметил никакой разницы между следующим:

new Thread(SomeMethod).Start();

new Thread(new ParameterizedThreadStart(SomeMethod));

и

new Thread(new ThreadStart(SomeMethod));

В чем разница, если вообще есть?

Ответ 1

Конструктор Thread(ThreadStart) можно использовать только тогда, когда подпись вашего метода SomeMethod совпадает с делегатом ThreadStart. И наоборот, Thread(ParameterizedThreadStart) требует, чтобы SomeMethod соответствовал делегату ParameterizedThreadStart. Подписи ниже:

public delegate void ThreadStart()
public delegate void ParameterizedThreadStart(Object obj)

Конкретно, это означает, что вы должны использовать ThreadStart, когда ваш метод не принимает никаких параметров, и ParameterizedThreadStart, когда он принимает один параметр Object. Потоки, созданные с помощью первого, следует запускать с помощью вызова Start(), в то время как потоки, созданные с последним, должны указывать свой аргумент через Start(Object).

public static void Main(string[] args)
{
    var threadA = new Thread(new ThreadStart(ExecuteA));
    threadA.Start();

    var threadB = new Thread(new ParameterizedThreadStart(ExecuteB));
    threadB.Start("abc");

    threadA.Join();
    threadB.Join();
}

private static void ExecuteA()
{
    Console.WriteLine("Executing parameterless thread!");
}

private static void ExecuteB(Object obj)
{
    Console.WriteLine($"Executing thread with parameter \"{obj}\"!");
}

Наконец, вы можете вызывать конструкторы Thread без указания делегата ThreadStart или ParameterizedThreadStart. В этом случае компилятор сопоставит ваш метод с перегрузкой конструктора на основе своей сигнатуры, выполнив приведение неявно.

var threadA = new Thread(ExecuteA);   // implicit cast to ThreadStart
threadA.Start();

var threadB = new Thread(ExecuteB);   // implicit cast to ParameterizedThreadStart
threadB.Start("abc");

Ответ 2

new Thread(SomeMethod) и new Thread(new ThreadStart(SomeMethod)):

Разница между new Thread(SomeMethod) и new Thread(new ThreadStart(SomeMethod)) является чисто синтаксической: компилятор С# генерирует для них одинаковый код; первая версия является аббревиатурой последнего.

(Компилятор может автоматически вывести подходящий тип делегата для использования из подписей доступных конструкторов Thread и сигнатуры указанного метода SomeMethod. Выписывание new ThreadStart(…) вместо просто является немного похоже на замену var фактическим типом некоторого выражения, вы избавляете компилятор от работы с фактическим типом.)

Эти две версии работают, когда SomeMethod не принимает никаких параметров, потому что подпись должна соответствовать делегату ThreadStart.

new Thread(new ParameterizedThreadStart(SomeMethod)):

Разница между двумя выше и new Thread(new ParameterizedThreadStart(SomeMethod)) заключается в том, что этот вызов вызывает другой конструктор на Thread.

И что ParameterizedThreadStart запрещает другую подпись метода, чем ThreadStart: вашему SomeMethod необходимо принять один аргумент типа object, иначе он не будет соответствовать этому типу делегата.

Ответ 3

Нет, но есть много раз, когда ваш код выглядит намного приятнее, если вы создаете объект ThreadStart в одном месте и запускаете новый поток в другом месте.