[英]C# Anonymous Thread with Lambda Syntax
一般来说,我得到了C#的lambda语法。 但是匿名线程语法对我来说并不完全清楚。 有人可以解释这样的线程创建实际上在做什么吗? 请尽可能详细,我希望能够逐步实现让这项工作变得神奇的魔力。
(new Thread(() => {
DoLongRunningWork();
MessageBox.Show("Long Running Work Finished!");
})).Start();
我真的不明白的部分是Thread(() => ...
当我使用这种语法时,似乎我删除了传统ThreadStart
的许多限制,例如必须在没有参数的方法上调用。
谢谢你的帮助!
() => ...
只是意味着lambda表达式不带参数。 您的示例等效于以下内容:
void worker()
{
DoLongRunningWork();
MessageBox.Show("Long Running Work Finished!");
}
// ...
new Thread(worker).Start();
lambda中的{ ... }
允许你在lambda体中使用多个语句,通常你只允许表达式。
这个:
() => 1 + 2
相当于:
() => { return (1 + 2); }
由于在我开始之前有一些答案,我将写下额外的参数如何进入lambda。
简而言之,这个东西叫做封闭 。 让我们用new Thread(() => _Transaction_Finalize_Worker(transId, machine, info, newConfigPath)).Start();
剖析你的例子new Thread(() => _Transaction_Finalize_Worker(transId, machine, info, newConfigPath)).Start();
成为碎片。
对于闭包,类的字段和局部变量之间存在差异。 因此,我们假设transId
是类字段(因此可以通过this.transId
访问),而其他只是局部变量。
在幕后如果在类编译器中使用lambda创建具有不可描述名称的嵌套类,为了简单起见,我们将其命名为X
,并将所有局部变量放在那里。 它也在那里写lambda,所以它成为常规方法。 然后编译器重写您的方法,以便它在某个时刻创建X
并newConfigPath
用x.machine
, x.info
和x.newConfigPath
替换对machine
, info
和newConfigPath
访问。 还X
接收参考this
,所以λ-方法可以访问transId
经由parentRef.transId
。
嗯,它非常简化但接近现实。
UPD:
class A
{
private int b;
private int Call(int m, int n)
{
return m + n;
}
private void Method()
{
int a = 5;
a += 5;
Func<int> lambda = () => Call(a, b);
Console.WriteLine(lambda());
}
#region compiler rewrites Method to RewrittenMethod and adds nested class X
private class X
{
private readonly A _parentRef;
public int a;
public X(A parentRef)
{
_parentRef = parentRef;
}
public int Lambda()
{
return _parentRef.Call(a, _parentRef.b);
}
}
private void RewrittenMethod()
{
X x = new X(this);
x.a += 5;
Console.WriteLine(x.Lambda());
}
#endregion
}
这是在C#中创建线程的匿名方式,它只是启动线程(因为你使用的是Start();)以下2种方法是等效的。 如果你需要Thread变量来做某事(例如通过调用thread0.join()阻塞调用线程),那么你使用第二个。
new Thread(() =>
{
Console.WriteLine("Anonymous Thread job goes here...");
}).Start();
var thread0= new Thread(() =>
{
Console.WriteLine("Named Thread job goes here...");
});
thread0.Start();
现在是Thread方法的一部分。 如果你看到Thread声明,我们有以下内容(我省略了3个其他声明)。
public Thread(ThreadStart start);
线程将委托作为参数。 委托是指方法。 所以Thread接受一个委托参数。 ThreadStart声明如下。
public delegate void ThreadStart();
这意味着您可以将任何方法传递给Thread,它返回void并且不接受任何参数。 以下示例是等效的。
ThreadStart del = new ThreadStart(ThreadMethod);
var thread3 = new Thread(del);
thread3.Start();
ThreadStart del2 = ThreadMethod;
var thread4 = new Thread(del2);
thread4.Start();
var thread5 = new Thread(ThreadMethod);
thread5.Start();
//This must be separate method
public static void ThreadMethod()
{
Console.WriteLine("ThreadMethod doing important job...");
}
现在我们认为ThreadMethod方法做的很少,我们可以将它设置为本地和匿名。 所以我们根本不需要ThreadMethod方法。
new Thread( delegate ()
{
Console.WriteLine("Anonymous method Thread job goes here...");
}).Start();
在委托之后看到最后一个花括号等同于我们的ThreadMethod()。 您可以通过引入Lambda语句进一步缩短以前的代码(请参阅MSDN)。 这只是你正在使用,看看它是如何结束如下。
new Thread( () =>
{
Console.WriteLine("Lambda statements for thread goes here...");
}).Start();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.