C# 线程相关知识总结

2020-06-17 15:24:00王振洲

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# 线程的资料请关注易采站长站其它相关文章!