C#中的thread和task之 Thread & ThreadPool

简介

在.NET Framework/C#中,要提高系统的运行性能,可用使用Thread和新的Task。

Thread在.NET Framework 1.1中引入,是对Posix的thread的封装。如果后台的工作线程需要与用户界面交互,系统会进行限制,如果您需要运行与用户界面交互的后台线程,.NET Framework 2.0 版提供了 BackgroundWorker 组件,该组件可以使用事件与用户界面线程的跨线程封送进行通信。

Task是在.NET Framework 4中添加进来的。这是新的namespace:System.Threading.Tasks;它强调的是adding parallelism and concurrency to applications。在语法上,和lamda表达式更好地结合。

Thread

多线程MultiThread的技术由来已久。使用也简单。
实例:

using System;
using System.Threading;

public class Worker
{

   // This method that will be called when the thread is started
   public void WorkProcess()
   {
      while (true)
      {
         Console.WriteLine("Worker.WorkProcess is running in its own thread.");
         Thread.Sleep(500);
      }
   }
};

public class ThreadSimple
{
   public static int Main()
   {
      Console.WriteLine("Thread Start/Stop/Join Sample");

      Worker oWorker = new Worker();

      // Create the thread object, passing in the Worker.WorkProcess method
      // via a ThreadStart delegate. This does not start the thread.
      Thread oThread = new Thread(new ThreadStart(oWorker.WorkProcess));

      // Start the thread
      oThread.Start();

      // Spin for a while waiting for the started thread to become
      // alive:
      while (!oThread.IsAlive);

      // Put the Main thread to sleep for 1 millisecond to allow oThread
      // to do some work:
      Thread.Sleep(1);

      // Request that oThread be stopped
      oThread.Abort();

      // Wait until oThread finishes. 
      oThread.Join();

      Console.WriteLine();
      Console.WriteLine("Worker.WorkProcess has done");

      try 
      {
         Console.WriteLine("Try to restart the Worker.WorkProcess thread");
         oThread.Start();
      }
      catch (ThreadStateException) 
      {
         Console.Write("ThreadStateException trying to restart Worker.WorkProcess. ");
         Console.WriteLine("Expected since aborted threads cannot be restarted.");
      }
      return 0;
   }
}

ThreadPool

MS介绍说,如果在应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应这一般使用ThreadPool(线程池)来解决;而且使用Timer时,线程平时都处于休眠状态,只是周期性地被唤醒执行;实际在Timer内部也使用的是ThreadPool。

Note: ThreadPool是static类。

简单的MS示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ThreadPoolSimple
{
    class Program
    {
        public static void Main()
        {
            ThreadPool.SetMaxThreads(1000, 30);

            for (int i = 0; i < 5; i++)
            {
                Worker t = new Worker();
                ThreadPool.QueueUserWorkItem(new WaitCallback(t.ThreadProc), i);
            }

            Console.WriteLine("Main thread begin sleep");
            Thread.Sleep(100000);

            Console.WriteLine("finish");
        }

        public class Worker
        {
            public void ThreadProc(object i)
            {
                Console.WriteLine("Thread[" + i.ToString() + "]");
                Thread.Sleep(1000);
            }
        }
    }
}

但是,线程池的启动和终止不是我们程序所能控制的。而且线程池中的线程执行完之后是没有返回值的.

注意: 如果是需要马上被执行的任务操作,不适合使用ThreadPool,直接使用Thread并调用Start,让系统开始调度执行。

如果需要在线程间同步,可用使用同步的一下对象,如Mutex、ManualResetEvent等;

lock

在多线程中,如果对某资源的访问需要同步,则可用使用C#的lock关键字,对一个对象变量进行锁操作。这极大地简化了对资源锁定的操作,是一个很好的语法糖果。

来自MS的示例:

using System;
using System.Threading;

public class Example
{
   static Object obj = new Object();

   public static void Main()
   {
      ThreadPool.QueueUserWorkItem(ShowThreadInformation);
      var th1 = new Thread(ShowThreadInformation);
      th1.Start();
      var th2 = new Thread(ShowThreadInformation);
      th2.IsBackground = true;
      th2.Start();
      Thread.Sleep(500);
      ShowThreadInformation(null); 
   }

   private static void ShowThreadInformation(Object state)
   {
      lock (obj) {
         var th  = Thread.CurrentThread;
         Console.WriteLine("Managed thread #{0}: ", th.ManagedThreadId);
         Console.WriteLine("   Background thread: {0}", th.IsBackground);
         Console.WriteLine("   Thread pool thread: {0}", th.IsThreadPoolThread);
         Console.WriteLine("   Priority: {0}", th.Priority);
         Console.WriteLine("   Culture: {0}", th.CurrentCulture.Name);
         Console.WriteLine("   UI culture: {0}", th.CurrentUICulture.Name);
         Console.WriteLine();
      }   
   }
}

你可能感兴趣的:(C#,thread,.net,framework,线程)