zoukankan      html  css  js  c++  java
  • 多线程实战(三)线程池

     创建线程是昂贵的操作,所有为每个短暂的异步操作创建线程会产生显著的开销。为了解决这种短暂的任务,我们把它交给线程池(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("操作成功.");
                }
            }

  • 相关阅读:
    Entity Framework 6.1
    Entity Framework Code First学习系列
    oracle 监控执行的sql语句
    修改Oracle XE Listener 占用的1521、8080端口
    Oracle中使用Entity Framework 6.x Code-First
    ASP.Net MVC 数据处理
    权限系统
    订单处理减库存的设计
    表达式树,它与表达式、委托
    监听服务管理(转)
  • 原文地址:https://www.cnblogs.com/xchit/p/4783313.html
Copyright © 2011-2022 走看看