【问题标题】:Thread vs Threadstart线程与线程启动
【发布时间】:2015-04-25 07:15:21
【问题描述】:
在 C# 中,实际上,我没有观察到以下内容之间的任何区别:
new Thread(SomeMethod).Start();
,
new Thread(new ParameterizedThreadStart(SomeMethod));
和
new Thread(new ThreadStart(SomeMethod));
有什么区别,如果有的话?
【问题讨论】:
标签:
c#
.net
multithreading
【解决方案1】:
只有当SomeMethod 方法的签名与ThreadStart 委托匹配时,才能使用Thread(ThreadStart) 构造函数。相反,Thread(ParameterizedThreadStart) 要求 SomeMethod 匹配 ParameterizedThreadStart 委托。签名如下:
public delegate void ThreadStart()
public delegate void ParameterizedThreadStart(Object obj)
具体来说,这意味着当你的方法不带任何参数时你应该使用ThreadStart,而当它只带一个Object参数时你应该使用ParameterizedThreadStart。使用前者创建的线程应通过调用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}\"!");
}
最后,您可以在不指定 ThreadStart 或 ParameterizedThreadStart 委托的情况下调用 Thread 构造函数。在这种情况下,编译器将根据其签名将您的方法与构造函数重载相匹配,隐式执行强制转换。
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)) 之间的区别纯粹是语法上的:C# 编译器为它们生成相同的代码;前者是后者的缩写。
(编译器可以从可用的Thread构造函数的签名和指定方法SomeMethod的签名中自动推导出要使用的正确委托类型。写出new ThreadStart(…)而不是…是有点像用某些表达式的实际类型替换var,你省去了编译器找出实际类型的工作。)
这两个版本在 SomeMethod 不带参数时有效,因为这是匹配 ThreadStart 委托所需的签名。
new Thread(new ParameterizedThreadStart(SomeMethod)):
以上两个和new Thread(new ParameterizedThreadStart(SomeMethod))的区别在于,这个在Thread上调用了不同的构造函数。
而ParameterizedThreadStart 禁止与ThreadStart 不同的方法签名:您的SomeMethod 需要采用object 类型的一个参数,否则它与此委托类型不匹配。
【解决方案3】:
不,但是很多时候如果您在一个地方创建 ThreadStart 对象并在另一个地方启动新线程,您的代码看起来会好很多。