参考书目:Professional.C#.4.0.and.NET.4.pdf 以及 Pro .NET 4 Parallel Programming in C#.pdf
Parallel Program in C#中有Delegate的Asynchronous也有Thread的Asynchronous,前者已经在《C#异步调用详细》中阐述清楚了,那它跟Thread的有什么区别呢?
可能大家都混淆了,我也快糊涂了,C#中异步(并行)编程有几类:
1. Asynchronous Delegates
Asychronous calling is used when you have work items that should be handled in the background and you care when they finish.
2. BackgroundWorker
Use BackgroundWorker if you have a single task that runs in the background and needs to interact with the UI. and use it if you don't care when they finish their task. The task of marshalling data and method calls to the UI thread are handled automatically through its event-based model.
Avoid BackgroundWorker if (1) your assembly does not already reference the System.Windows.Form assembly, (2) you need the thread to be a foreground thread, or (3) you need to manipulate the thread priority.
3. ThreadPool
Use a ThreadPool thread when efficiency is desired. The ThreadPool helps avoid the overhead associated with creating, starting, and stopping threads.
Avoid using the ThreadPool if (1) the task runs for the lifetime of your application, (2) you need the thread to be a foreground thread, (3) you need to manipulate the thread priority, or (4) you need the thread to have a fixed identity (aborting, suspending, discovering).
4. Thread class
Use the Thread class for long-running tasks and when you require features offered by a formal threading model, e.g., choosing between foreground and background threads, tweaking the thread priority, fine-grained control over thread execution, etc.
5. Task Parallel Library
Task/TaskFactory, Parallel.For, Parallel.ForEach, Parallel.Invoke
6. Parallel LINQ
TBD
好了进入主题了,先来介绍Thread命名空间。
Thread class
创建与指定委托(Create):
can be constructed with two kinds of delegate:
1. ThreadStart: void ()(void)
2. ParameterizedThreadStart: void ()(Object obj)
跟Asynchronous delegate 相比,输入参数已经很受限制,才支持一个,而且还是object对象的,没有进行类型检查。
控制:
Start() or Start(obj)
Start是直接让新创建的异步执行,类似于Asynchronous的BeginInvoke方法,就是异步于caller来执行。
下面的代码分别显示Asynchronous Delegate以及Thread做同样的事情
Asynchronous Delegate部分
public void AsyncOperation(int data)
{
int i = 0;
while (i++ < data)
{
Thread.Sleep(1000);
Console.WriteLine(string.Format("Running for {0} seconds, in thread id: {1}.", i, Thread.CurrentThread.ManagedThreadId));
}
}
public delegate void AsyncOperationDelegate(int data);
public void RunBeginInvoke()
{
AsyncOperationDelegate d1 = new AsyncOperationDelegate(AsyncOperation);
d1.BeginInvoke(3, null, null);
int i = 0;
while (i++ < 3)
{
Thread.Sleep(1000);
Console.WriteLine(string.Format("[BeginInvoke]Running for {0} seconds, in thread id: {1}.", i, Thread.CurrentThread.ManagedThreadId));
}
}
Thread部分:
private void AsyncOperation(object obj)
{
int data = (int)obj;
int i = 0;
while (i++ < data)
{
Thread.Sleep(1000);
Console.WriteLine(string.Format("Running for {0} seconds, in thread id: {1}.", i, Thread.CurrentThread.ManagedThreadId));
}
}
public void RunThread()
{
Thread t1 = new Thread(new ParameterizedThreadStart(AsyncOperation));
t1.Start((object)3);
int i = 0;
while (i++ < 3)
{
Thread.Sleep(1000);
Console.WriteLine(string.Format("[Thread]Running for {0} seconds, in thread id: {1}.", i, Thread.CurrentThread.ManagedThreadId));
}
}
使用起来比Asynchronous Delegate实在别扭以及难看。
书中提议使用类的成员函数作为委托函数,同时由于类成员函数能否访问类的成员变量,从而实现复杂或者多个参数传递,或者获取修改后的值。具体例子如下:
class ThreadData
{
public int data = 0;
public ThreadData()
{
}
public void RunThread()
{
int i = 0;
while (i++ < 1000000)
data++;