Lambda简洁高效,但是在捕获变量的时候要注意,捕获的变量是否共享。
如:
for (int i = 0; i < 10; i++) new Thread (() => Console.Write (i)).Start();
输出
0223447899
因为每次循环中的i都是同一个i,是共享变量,在输出的过程中,i的值会发生变化。
解决方法-局部域变量
for (int i = 0; i < 10; i++)
{
int temp = i;
new Thread (() => Console.Write (temp)).Start();
}
这时每个线程都指向新的域变量temp(此时每个线程都有属于自己的花括号的域变量)在该线程中temp不受其他线程影响。
委托
委托可以有任意个传入和输出参数。以Action,Func来举例。
Action 有零个或多个传入参数,但是没有返回值。 Func 有零个或多个传入参数,和一个返回值。
Func<string, int> method = Work;
IAsyncResult cookie = method.BeginInvoke("test", null, null);
//
// ... 此时可以同步处理其他事情
//
int result = method.EndInvoke(cookie);
Console.WriteLine("String length is: " + result);
int Work(string s) { return s.Length; }
使用回调函数获取返回值
static void Main()
{
Func<string, int> method = Work;
method.BeginInvoke ("test", Done, null);
// ...
//并行其他事情
}
static int Work (string s) { return s.Length; }
static void Done (IAsyncResult cookie)
{
var target = (Func<string, int>) cookie.AsyncState;
int result = target.EndInvoke (cookie);
Console.WriteLine ("String length is: " + result);
}
EndInvoke做了三件事情:
等待委托异步的结束。 获取返回值。 抛出未处理异常给调用线程。Task
Task泛型允许有返回值。
如:
static void Main()
{
// 创建Task并执行
Task<string> task = Task.Factory.StartNew<string>
( () => DownloadString ("http://www.baidu.com") );
// 同时执行其他方法
Console.WriteLine("begin");
//等待获取返回值,并且不会阻塞主线程
Console.WriteLine(task.Result);
Console.WriteLine("end");
}
static string DownloadString (string uri)
{
using (var wc = new System.Net.WebClient())
return wc.DownloadString (uri);
}
参考:
http://www.albahari.com/threading/
以上就是C# 线程相关知识总结的详细内容,更多关于C# 线程的资料请关注易采站长站其它相关文章!










