您的位置:首页 > 其它

多线程实战(三)线程池

2015-09-05 16:18 274 查看
创建线程是昂贵的操作,所有为每个短暂的异步操作创建线程会产生显著的开销。为了解决这种短暂的任务,我们把它交给线程池(pooling);线程池可以成功地适应任何需要大量短暂开销资源情况。我们事先分配一定的资源,将这些资源放入到资源池。每次需要新的资源,只需要从池中获取一个,而不是创建一个新的。当资源不在被使用,就将其返回到池中;

ThreadPool

异步

CancellationTokenSource 类

RegisterWaitForSingleObject

ThreadPool

1.创建线程池

static void Main1(string[] args)
{
ThreadPool.QueueUserWorkItem(AsyncOperation);
Console.ReadKey();
}

private static void AsyncOperation(object state)
{
Console.WriteLine("参数状态: {0}", state ?? "(null)");
Console.WriteLine("工作线程ID: {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
}


2.参数传递

static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(AsyncOperation);
ThreadPool.QueueUserWorkItem(AsyncOperation,"妹子");
Console.ReadKey();
}

private static void AsyncOperation(object state)
{
Console.WriteLine("参数状态: {0}", state ?? "(null)");
Console.WriteLine("工作线程ID: {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
}




3.另外的写法

static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(AsyncOperation);
ThreadPool.QueueUserWorkItem(AsyncOperation,"妹子");

ThreadPool.QueueUserWorkItem(state =>
{
Console.WriteLine("参数状态: {0}", state);
Console.WriteLine("工作线程ID: {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(TimeSpan.FromSeconds(2));
}, "妹子");

Console.ReadKey();
}

private static void AsyncOperation(object state)
{
Console.WriteLine("参数状态: {0}", state ?? "(null)");
Console.WriteLine("工作线程ID: {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
}




异步

static void Main()
{
int threadId = 0;
RunOnThreadPool poolDelegate = Test1;
IAsyncResult r = poolDelegate.BeginInvoke(out threadId, Callback1, "异步回调参数");
string result = poolDelegate.EndInvoke(out threadId, r);
Console.WriteLine(result);
Console.ReadKey();
}

private delegate string RunOnThreadPool(out int threadId);

private static void Callback1(IAsyncResult ar)
{
Console.WriteLine("开始回调");
Console.WriteLine("传入回掉的值: {0}", ar.AsyncState);
Console.WriteLine("回掉是否是托管线程池: {0}", Thread.CurrentThread.IsThreadPoolThread);
Console.WriteLine("线程iD: {0}", Thread.CurrentThread.ManagedThreadId);
}

private static string Test1(out int threadId)
{
Console.WriteLine("开始异步...");
Console.WriteLine("是否是托管线程池: {0}", Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(2));
threadId = Thread.CurrentThread.ManagedThreadId;
return string.Format("池中线程ID: {0}", threadId);
}




异步回调也是输入托管线程池

CancellationTokenSource 类

通知 CancellationToken,告知其应被取消。

static void Main(string[] args)
{
using (var cts = new CancellationTokenSource())
{
CancellationToken token = cts.Token;
ThreadPool.QueueUserWorkItem(_ => AsyncOperation1(token));
Thread.Sleep(TimeSpan.FromSeconds(2));
cts.Cancel();
}

using (var cts = new CancellationTokenSource())
{
CancellationToken token = cts.Token;
ThreadPool.QueueUserWorkItem(_ => AsyncOperation2(token));
Thread.Sleep(TimeSpan.FromSeconds(2));
cts.Cancel();
}

using (var cts = new CancellationTokenSource())
{
CancellationToken token = cts.Token;
ThreadPool.QueueUserWorkItem(_ => AsyncOperation3(token));
Thread.Sleep(TimeSpan.FromSeconds(2));
cts.Cancel();
}

Thread.Sleep(TimeSpan.FromSeconds(2));

Console.ReadKey();
}

static void AsyncOperation1(CancellationToken token)
{
Console.WriteLine("Starting the first task");
for (int i = 0; i < 5; i++)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("The first task has been canceled.");
return;
}
Thread.Sleep(TimeSpan.FromSeconds(1));
}
Console.WriteLine("The first task has completed succesfully");
}

static void AsyncOperation2(CancellationToken token)
{
try
{
Console.WriteLine("Starting the second task");

for (int i = 0; i < 5; i++)
{
token.ThrowIfCancellationRequested();
Thread.Sleep(TimeSpan.FromSeconds(1));
}
Console.WriteLine("The second task has completed succesfully");
}
catch (OperationCanceledException)
{
Console.WriteLine("The second task has been canceled.");
}
}

private static void AsyncOperation3(CancellationToken token)
{
bool cancellationFlag = false;
token.Register(() => cancellationFlag = true);
Console.WriteLine("Starting the third task");
for (int i = 0; i < 5; i++)
{
if (cancellationFlag)
{
Console.WriteLine("The third task has been canceled.");
return;
}
Thread.Sleep(TimeSpan.FromSeconds(1));
}
Console.WriteLine("The third task has completed succesfully");
}




RegisterWaitForSingleObject

RegisterWaitForSingleObject提供了一些简单的线程间交互

static void Main(string[] args)
{
RunOperations(TimeSpan.FromSeconds(5));
RunOperations(TimeSpan.FromSeconds(7));
Console.ReadKey();
}

static void RunOperations(TimeSpan workerOperationTimeout)
{
using (var evt = new ManualResetEvent(false))
using (var cts = new CancellationTokenSource())
{
Console.WriteLine("注册超时行为...");
var worker = ThreadPool.RegisterWaitForSingleObject(evt,
(state, isTimedOut) => WorkerOperationWait(cts, isTimedOut), null, workerOperationTimeout, true);

Console.WriteLine("启动长时间运行...");

ThreadPool.QueueUserWorkItem(_ => WorkerOperation(cts.Token, evt));

Thread.Sleep(workerOperationTimeout.Add(TimeSpan.FromSeconds(2)));
worker.Unregister(evt);
}
}

static void WorkerOperation(CancellationToken token, ManualResetEvent evt)
{
for(int i = 0; i < 6; i++)
{
if (token.IsCancellationRequested)
{
return;
}
Thread.Sleep(TimeSpan.FromSeconds(1));
}
evt.Set();
}

static void WorkerOperationWait(CancellationTokenSource cts, bool isTimedOut)
{
if (isTimedOut)
{
cts.Cancel();
Console.WriteLine("超时取消.");
}
else
{
Console.WriteLine("操作成功.");
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: