.net 多线程笔记

来源:互联网 发布:windows 界面设计 编辑:程序博客网 时间:2024/04/28 22:59
 

1.线程一旦结束,就无法从新开始。
2.线程阻塞的时候不消耗CPU资源。在调用Sleep和Join的时候,都会阻塞线程。
3.Thread.Sleep(0),交出当前的CPU时间片给其他线程。
  在.net Framework 4.0中 线程的 Yield()方法,会产生同样效果,不过是把当前时间片交给运行在同一CPu的其他线程。
4.线程的正确用途
  4.1 保持用户界面的有效响应。
  4.2 有效利用CPU:比如一个线程因等待用户输入而阻塞后,其他线程可以利用该CPU。
  4.3 并行编程:如果工作可以分割,并行运行则可以有效利用多CPU和多核CPU。
  4.4 预测执行.
  4.5 允许请求同步处理。

5.创建线程三种方法:
  5.1 ThreadStart delegate:Thread t = new Thread (new ThreadStart (Go));
  5.2 a method group       Thread t = new Thread (Go);
  5.3 lambda expression or anonymous method:Thread t = new Thread ( () => Console.WriteLine ("Hello!") );
6.前台和后台线程
  所有显式建立的线程都是前台线程。
  前台:只要有一个前台线程存活,应用程序就会保持活动。
  后台:所有前台线程结束后,后台线程会立刻终止,并且不会调用finally中内容。如果必须要幽雅结束可以采用join ,如果是线程池,可以采用等待一个事

件的方式解决。这两种方式都需要指定一个超时时间。
  如果用户采用任务管理器强制退出,则所有线程都以后台线程的方式结束。
7. 异常处理
  在任何try/catch/finally块中的创建线程代码,都和线程执行本身无关。
 
public static void Main()
{
try
{
new Thread (Go).Start();
}
catch (Exception ex)
{
// 永远不会获取GO()函数中抛出的异常
Console.WriteLine ("Exception!");
}
}
static void Go() { throw null; }
 应该按如下方法获取异常
public static void Main()
{
new Thread (Go).Start();
}
static void Go()
{
try
{
...
throw null; // The NullReferenceException will get caught below
...
}
catch (Exception ex)
{
Typically log the exception, and/or signal another thread
that we've come unstuck
...
}
}
这是因为每个线程都有独立的异常路径。

8.(Application.DispatcherUnhandledException and Application.ThreadException)
 只对main UI thread启作用。
9.线程池
 9.1  一个线程大概需要1M空间。
 9.2 有如下几种方式进入线程池:
     通过Task Parallel Library(from framework 4.0)
     通过调用ThreadPool.QueueUserWorkItem
     采用异步代理
     采用后台线程。
 9.3下面是间接几个使用线程池的例子
    WCF,Remoting,ASP.NET AXMX Web Service应用服务器。
    System.Timers.Timer和System.Threading.Timer
    框架方法,比如以Async结束的方法和以Begin结束的方法。
    PLINQ。
 9.4使用线程池的注意事项:
    不能设置池化线程的名称,可以只是描述。
    池化线程多为后台线程。
    阻塞一个池化线程会触发额外的延迟。除非你调用了ThreadPool.SetMinThread().
    可以改变池化线程的优先级,但是当该线程释放后,该线程优先级会恢复为Normal。
    Thread.CurrentThread.IsThreadPoolThread,该属性表示当前线程是否为池化线程。\
10.通过TPL进入线程池。未完待续...