您的位置:首页 > 编程语言 > C#

C#中的thread和task之 Thread & ThreadPool

2017-08-22 11:10 381 查看

简介

在.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();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: