ThreadPool的浅研究

线程的开销

1.线程有其自己的数据结构,创建一个线程需要存储空间

2.操作系统要调度线程,当线程切换(Context Switch)时

3.线程执行完任务后要销毁,释放其所占用的资源,同样影响性能

基于上述创建线程可能带来的问题,这就是为什么需要线程池了

每个CLR有一个线程池,CLR的所有AppDomain共享一个线程池,CLR初始化时线程池是没有线程的,当线程池收到请求时,线程池试图只用一个线程去执行任务,当有更多的请求而一个线程不能满足,线程池会创建一个新的线程来执行新的请求;应用程序最终达到一个能用少数的线程满足所有请求的状态,而没有必要创建过多的线程。

当线程池里的线程执行完任务后,不会被销毁,而是等待分配下一个任务,不会销毁也就没有销毁带来的性能问题。但是当你的程序不在请求线程池时,线程池可能有许多线程无事可做,其实这是一中浪费,至少浪费了内存,所以,这时候闲置的线程会唤醒自己然后销毁自己(自杀),这时候销毁线程不会后性能问题,因为你的线程是在闲置才销毁自己的。

 

如何使用线程池

下面是几种方式使用线程此

Via the Task ParallelLibrary (from Framework 4.0)

By calling ThreadPool.QueueUserWorkItem

Via asynchronousdelegates

Via BackgroundWorker

用TPL来使用线程池

static void Main()    // The Task class is inSystem.Threading.Tasks

{

  Task.Factory.StartNew (Go);

}

 

static void Go()

{

  Console.WriteLine ("Hello from the threadpool!");

}

 

带返回值的task

static void Main()

{

  // Start the task executing:

  Task<string> task = Task.Factory.StartNew<string>

    ( () => DownloadString ("http://www.linqpad.net"));

 

  // We can do other work here and it will execute inparallel:

  RunSomeOtherMethod();

 

  // When we need the task's return value, we query itsResult property:

  // If it's still executing, the current thread willnow block (wait)

  // until the task finishes:

  string result = task.Result;

}

 

static string DownloadString (string uri)

{

  using (var wc = new System.Net.WebClient())

    return wc.DownloadString (uri);

}

不使用TPL,使用QueueUserWorkItem

static void Main()

{

  ThreadPool.QueueUserWorkItem (Go);

  ThreadPool.QueueUserWorkItem (Go, 123);

  Console.ReadLine();

}

 

static void Go (object data)   // data will be nullwith the first call.

{

  Console.WriteLine ("Hello from the thread pool!" + data);

}

 Asynchronous delegates异步代理

ThreadPool.QueueUserWorkItem doesn’t provide an easymechanism for getting return values back from a thread after it has finishedexecuting. Asynchronous delegate invocations (asynchronous delegates for short)solve this, allowing any number of typed arguments to be passed in both directions.Furthermore, unhandled exceptions on asynchronous delegates are convenientlyrethrown on the original thread (or more accurately, the thread that calls EndInvoke),and so they don’t need explicit handling.

Here’s how you start a worker task via an asynchronousdelegate:

Instantiate a delegate targeting the method you want to runin parallel (typically one of the predefinedFunc delegates).

Call BeginInvoke on the delegate, saving its IAsyncResult returnvalue.

BeginInvoke returns immediately to the caller. You can then perform otheractivities while the pooled thread is working.

When you need the results, call EndInvoke on thedelegate, passing in the saved IAsyncResult object.

 

 

static void Main()

{

  Func<string, int> method = Work;

  IAsyncResult cookie = method.BeginInvoke ("test",null, null);

  //

  // ... here's where we can do other work inparallel...

  //

  int result = method.EndInvoke (cookie);

  Console.WriteLine ("String length is: " +result);

}

 

static int Work (string s) { return s.Length; }

EndInvoke does threethings. First, it waits for the asynchronous delegate to finish executing, ifit hasn’t already. Second, it receives the return value (as well as any ref or out parameters).Third, it throws any unhandled worker exception back to the calling thread.

You can also specify a callback delegate when calling BeginInvoke —a method accepting an IAsyncResultobject that’s automatically called uponcompletion. This allows the instigating thread to “forget” about theasynchronous delegate, but it requires a bit of extra work at the callback end:

static void Main()

{

  Func<string, int> method = Work;

  method.BeginInvoke ("test", Done, method);

  // ...

  //

}

 

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);

}

The final argument to BeginInvoke isa user state object that populates the AsyncState property ofIAsyncResult.It can contain anything you like; in this case, we’re using it to pass the method delegateto the completion callback, so we can call EndInvoke on it.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值