向线程池中放入异步操作
代码Demo:
using System;
using System.Threading;
在Main方法下面加入以下代码片段:
private static void AsyncOperation(object state)
{
Console.WriteLine("Operation state:{0}", state ?? "(null)");
Console.WriteLine("Worker thread id:{0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(TimeSpan.FromSeconds(2));
}
在Main方法中加入以下代码片段:
const int x = 1;
const int y = 2;
const string lambdaState = "lambda state 2";
ThreadPool.QueueUserWorkItem(AsyncOperation);
Thread.Sleep(TimeSpan.FromSeconds(1));
ThreadPool.QueueUserWorkItem(AsyncOperation, "async state");
Thread.Sleep(TimeSpan.FromSeconds(1));
ThreadPool.QueueUserWorkItem(state =>
{
Console.WriteLine("Operation state:{0}", state);
Console.WriteLine("Worker thread id:{0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(TimeSpan.FromSeconds(2));
}, "lambda state");
ThreadPool.QueueUserWorkItem(_ =>
{
Console.WriteLine("Operation state:{0},{1}", x + y, lambdaState);
Console.WriteLine("Worker thread id:{0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(TimeSpan.FromSeconds(2));
}, "lambda state");
Thread.Sleep(TimeSpan.FromSeconds(2));
工作原理:
首先定义了AsyncOperation方法,其接受单个object类型的参数。然后使用QueueUserWorkItem方法将该方法放到线程池中。接着再次放入该方法,但是这次给方法调用传入了一个状态对象。该对象将作为状态参数传递给AsynchronousOperation方法。
在操作完成后让线程睡眠一秒钟,从而让线程池拥有为新操作重用线程的可能性。如果注释掉所有的Thread.Sleep调用,那么所有打印出的线程ID多半是不一样的。如果ID是一样的,那很可能是前两个线程被重用来运行接下来的两个操作。
首先将一个lambda表达式放置到线程池中。这里没什么特别的。我们使用了lambda表达式语法,从而无须定义一个独特的方法。
然后,我们使用闭包机制,从而无须传递lambda表达式的状态。闭包更灵活,允许我们向异步操作传递一个以上的对象而且这些对象具有静态类型。所以以前介绍的传递对象给方法回调的机制既冗余又过时。在c#中有了闭包后就不在需要使用它了。