只要有一个前台线程在运行,应用程序就在运行;如果有多个前台线程在运行,而Main()方法结束了,应用程序进程仍然时激活的,直到所有前台线程完成为止。
Delegate是通过线程池线程完成异步调用的,线程池线程总是后台线程。
///
/// 只要有一个前台线程在运行,应用程序就在运行;
/// 如果有多个前台线程在运行,而Main()方法结束了,
/// 应用程序进程仍然时激活的,直到所有前台线程完成为止。
/// Delegate是通过线程池线程完成异步调用的,线程池线程总是后台线程。
///
public class DelegateWay1
{
public delegate int ThreadFunDelegate(int data, int ms);
///
/// 线程函数
///
private static int ThreadFun(int data, int ms)
{
Thread.Sleep(ms);
System.Diagnostics.Debug.WriteLine(String.Format("[ThreadFun] data = {0:D}, ms = {1:D}", data, ms));
return ++data;
}
///
/// 示例1
///
public static void DemoThread1()
{
ThreadFunDelegate dl = ThreadFun;
//触发异步执行
IAsyncResult ar = dl.BeginInvoke(1, 5000, null, null);
//等待执行完成
int ret = dl.EndInvoke(ar);//也可以使用IAsyncResult.WaitHandle对象来等待
System.Diagnostics.Debug.WriteLine("thread finished, return: " + ret);
}
///
/// 委托线程完成时的回调函数(从委托线程调用)
///
private static void AsyncCallbackFun(IAsyncResult ar)
{
if(null != ar)
{
//BeginInvoke的第4各参数,可以通过IAsyncResult.AsyncState获取
ThreadFunDelegate dl = ar.AsyncState as ThreadFunDelegate;
//获取结果
int ret = dl.EndInvoke(ar);
System.Diagnostics.Debug.WriteLine("callback function: " + ret);
}
}
///
/// 示例2
///
public static void DemoThread2()
{
ThreadFunDelegate dl = ThreadFun;
//触发异步执行
IAsyncResult ar = dl.BeginInvoke(1, 5000, AsyncCallbackFun, dl);
System.Diagnostics.Debug.WriteLine("main thread continue ...");
}
}
//运行示例1
private void button1_Click(object sender, EventArgs e)
{
DelegateWay1.DemoThread1();
}
//运行示例2
private void button2_Click(object sender, EventArgs e)
{
DelegateWay1.DemoThread2();
}
默认情况下Thread类创建的线程总是前台线程,需要修改IsBackground属性来指定。
///
/// 只要有一个前台线程在运行,应用程序就在运行;
/// 如果有多个前台线程在运行,而Main()方法结束了,
/// 应用程序进程仍然时激活的,直到所有前台线程完成为止。
/// Delegate是通过线程池线程完成异步调用的,线程池线程总是后台线程
/// 默认情况下Thread类创建的线程总是前台线程,需要修改IsBackground属性来指定。
///
public class MyData
{
public int id;
public string name;
}
public class ThreadWay1
{
///
/// 不带参数的线程函数
///
private static void ThreadFun()
{
Thread.Sleep(3000);
System.Diagnostics.Debug.WriteLine("[Thread] thread is finished");
}
///
/// 示例1 - 不带参数的线程
///
public static void ThreadDemo1()
{
//通过ThreadStart创建不带参数的线程
var t1 = new Thread(ThreadFun);
//启动线程
t1.Start();
}
///
/// 带参数的线程函数
///
private static void ThreadFunWithParam(object data)
{
MyData d = (MyData)data;
System.Diagnostics.Debug.WriteLine(String.Format("[Thread] {0:D}, {1}", d.id, d.name));
}
///
/// 示例2 - 带参数的线程
///
public static void ThreadDemo2()
{
var data = new MyData() { id = 10, name = "your name" };
var t2 = new Thread(ThreadFunWithParam);
t2.Start(data);
}
///
/// 示例3 - 通过类实现传递线程参数
///
public static void ThreadDemo3()
{
var threadObj = new MyThread("this is a thread object");
var t3 = new Thread(threadObj.ThreadFunc);
t3.Start();
Thread.Sleep(1000);
threadObj.IsStop = true;//停止线程
}
///
/// 示例4 - 指定后台线程
///
public static void ThreadDemo4()
{
var t4 = new Thread(ThreadFun) { IsBackground = false };
t4.Start();
}
}
public class MyThread
{
private string data;
private Boolean isStop = false;
public Boolean IsStop { get=>isStop; set=>isStop=value; }
public MyThread(string data)
{
this.data = data;
}
///
/// 线程函数
///
public void ThreadFunc()
{
while (!IsStop)
{
System.Diagnostics.Debug.WriteLine(String.Format("[Thread] {0}", data));
}
}
}
使用线程池有一定的条件限制:
///
/// 线程池有限制:
/// 线程池中的线程都是后台线程
/// 不能给线程池中的线程设置名称和优先级
/// 线程池中的线程都是多线程单元线程(multithreaded apartment,MTA),但许多COM对象需要单线程单元线程(single-threaded apartment, STA)
/// 线程池用于时间较短的任务,长时间的如Word拼写检查,应该使用Thread类创建一个线程
///
public class ThreadPoolWay
{
private static void JobThread(object state)
{
for(int i=0; i<3; ++i)
{
System.Diagnostics.Debug.WriteLine("loop {0}: running in pooled thread {1}.", i, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(50);
}
}
public static void ThreadDemo1()
{
int nWorkerThreads;
int nCompletionPortThreads;
ThreadPool.GetMaxThreads(out nWorkerThreads, out nCompletionPortThreads);
System.Diagnostics.Debug.WriteLine("max worker threads: {0}, I/O completion threads: {1}.", nWorkerThreads, nCompletionPortThreads);
for(int i=0; i<5; ++i)
{
ThreadPool.QueueUserWorkItem(JobThread);
}
}
}
System.Threading.Tasks中的TaskFactory、Task类抽象出了线程的功能,在后台使用ThreadPool.任务提供了非常大的灵活性,比如:
///
/// System.Threading.Tasks中的TaskFactory、Task类抽象出了线程的功能,在后台使用ThreadPool.
/// 任务提供了非常大的灵活性,比如:
/// 可以定义一系列按顺序执行的工作(在一个任务完成后继续执行另外一个任务);
/// 可以在层次结构中安排任务,父任务可以创建新的子任务,取消父任务,也会取消其子任务。
///
public class TaskWay
{
private static void TaskFunc()
{
Thread.Sleep(3000);
System.Diagnostics.Debug.WriteLine("Task id: {0}", Task.CurrentId);
}
///
/// 示例1 - 启动任务
///
public static void ThreadDemo1()
{
//使用TaskFactory启动任务
TaskFactory tf = new TaskFactory();
Task t1 = tf.StartNew(TaskFunc);//TaskCreationOptions.LongRunning
//使用Task.Factory启动任务
Task t2 = Task.Factory.StartNew(TaskFunc);
//使用Task构造函数
Task t3 = new Task(TaskFunc);
t3.Start();
}
private static void DoFirst()
{
Thread.Sleep(3000);
System.Diagnostics.Debug.WriteLine("[DoFirst] Task id: {0}", Task.CurrentId);
}
private static void DoSecond(Task t)
{
Thread.Sleep(3000);
System.Diagnostics.Debug.WriteLine("[DoSecond] Task id: {0}, Task id = {1} finished", Task.CurrentId, t.Id);
}
///
/// 示例2 - 连续任务,不管前面的任务是否执行成功
///
public static void ThreadDemo2()
{
Task t1 = new Task(DoFirst);
Task t2 = t1.ContinueWith(DoSecond);
Task t3 = t1.ContinueWith(DoSecond);
Task t4 = t2.ContinueWith(DoSecond);
t1.Start();
}
private static void ChildTask()
{
System.Diagnostics.Debug.WriteLine("[ChildTask] start, task id {0}", Task.CurrentId);
Thread.Sleep(8000);
System.Diagnostics.Debug.WriteLine("[ChildTask] finished");
}
private static void ParentTask()
{
System.Diagnostics.Debug.WriteLine("[ParentTask] task id {0}", Task.CurrentId);
var child = new Task(ChildTask);
child.Start();
Thread.Sleep(5000);
System.Diagnostics.Debug.WriteLine("[ParentTask] started child task");
}
private static void ParentAndChild()
{
System.Diagnostics.Debug.WriteLine("[ParentAndChild] start, task id {0}", Task.CurrentId);
var parent = new Task(ParentTask);
parent.Start();
Thread.Sleep(2000);
System.Diagnostics.Debug.WriteLine("[ParentAndChild] parent status = {0}", parent.Status);
Thread.Sleep(4000);
System.Diagnostics.Debug.WriteLine("[ParentAndChild] parent status = {0}", parent.Status);
System.Diagnostics.Debug.WriteLine("[ParentAndChild] finished");
}
///
/// 示例3 - 任务的层次
///
public static void ThreadDemo3()
{
Task t1 = new Task(ParentAndChild);
t1.Start();
}
}
public class ParallelWay
{
///
/// 示例1
///
public static void ThreadDemo1()
{
//[0, 10)共10个task,也就是10个线程,特别注意迭代的顺序无意义不可预知
ParallelLoopResult result = Parallel.For(0, 10, i => {
System.Diagnostics.Debug.WriteLine("{0}, task: {1}, thread: {2}",
i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000);
});
System.Diagnostics.Debug.WriteLine(result.IsCompleted);
}
///
///示例2 - 控制循环
/// ParallelLoopState.Break()可以和其它迭代交互,阻止迭代index大于LowestBreakIteration的迭代启动,但不影响已经启动起来的迭代。
/// ParallelLoopState.Stop()则直接退出整个Parallel.For循环。
///
public static void ThreadDemo2()
{
ParallelLoopResult result = Parallel.For(0, 100, (int i, ParallelLoopState pls) => {
System.Diagnostics.Debug.WriteLine("beginning iteration {0,2}, task: {1,2}, thread: {2,2}",
i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000);
if(i == 40)//当改成i >= 40时,可以从运行结果体会"阻止迭代index大于LowestBreakIteration的迭代启动"
{
System.Diagnostics.Debug.WriteLine("*breaking iteration {0,2}, task: {1,2}, thread: {2,2}",
i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
pls.Break();
}
System.Diagnostics.Debug.WriteLine("completed iteration {0,2}, task: {1,2}, thread: {2,2}",
i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
});
System.Diagnostics.Debug.WriteLine(result.IsCompleted);
System.Diagnostics.Debug.WriteLine("lowest break iteration: {0}", result.LowestBreakIteration);
}
}
示例2 if(i == 40)的执行结果
beginning iteration 25, task: 2, thread: 3
beginning iteration 50, task: 3, thread: 5
beginning iteration 1, task: 5, thread: 6
beginning iteration 0, task: 1, thread: 1
beginning iteration 75, task: 4, thread: 4
beginning iteration 26, task: 6, thread: 7
completed iteration 25, task: 2, thread: 3
completed iteration 50, task: 3, thread: 5
beginning iteration 27, task: 8, thread: 3
completed iteration 0, task: 1, thread: 1
completed iteration 1, task: 5, thread: 6
beginning iteration 2, task: 1, thread: 1
beginning iteration 51, task: 9, thread: 5
completed iteration 75, task: 4, thread: 4
beginning iteration 4, task: 10, thread: 6
beginning iteration 76, task: 11, thread: 4
beginning iteration 53, task: 7, thread: 8
completed iteration 26, task: 6, thread: 7
beginning iteration 29, task: 13, thread: 7
completed iteration 27, task: 8, thread: 3
beginning iteration 28, task: 8, thread: 3
completed iteration 2, task: 1, thread: 1
completed iteration 51, task: 9, thread: 5
beginning iteration 52, task: 9, thread: 5
completed iteration 4, task: 10, thread: 6
completed iteration 76, task: 11, thread: 4
beginning iteration 3, task: 1, thread: 1
beginning iteration 5, task: 10, thread: 6
beginning iteration 77, task: 11, thread: 4
beginning iteration 78, task: 12, thread: 9
completed iteration 53, task: 7, thread: 8
beginning iteration 54, task: 15, thread: 8
completed iteration 29, task: 13, thread: 7
beginning iteration 30, task: 13, thread: 7
completed iteration 28, task: 8, thread: 3
beginning iteration 31, task: 16, thread: 3
completed iteration 52, task: 9, thread: 5
beginning iteration 56, task: 17, thread: 5
completed iteration 3, task: 1, thread: 1
completed iteration 5, task: 10, thread: 6
completed iteration 77, task: 11, thread: 4
beginning iteration 79, task: 19, thread: 4
beginning iteration 6, task: 1, thread: 1
beginning iteration 10, task: 18, thread: 6
completed iteration 78, task: 12, thread: 9
beginning iteration 14, task: 14, thread: 10
beginning iteration 83, task: 21, thread: 9
completed iteration 54, task: 15, thread: 8
beginning iteration 55, task: 15, thread: 8
completed iteration 30, task: 13, thread: 7
beginning iteration 35, task: 22, thread: 7
completed iteration 31, task: 16, thread: 3
beginning iteration 32, task: 16, thread: 3
completed iteration 56, task: 17, thread: 5
beginning iteration 57, task: 17, thread: 5
completed iteration 79, task: 19, thread: 4
completed iteration 6, task: 1, thread: 1
completed iteration 10, task: 18, thread: 6
beginning iteration 7, task: 1, thread: 1
beginning iteration 11, task: 18, thread: 6
beginning iteration 80, task: 19, thread: 4
beginning iteration 39, task: 20, thread: 11
completed iteration 14, task: 14, thread: 10
completed iteration 55, task: 15, thread: 8
completed iteration 35, task: 22, thread: 7
completed iteration 83, task: 21, thread: 9
beginning iteration 84, task: 21, thread: 9
beginning iteration 60, task: 25, thread: 8
completed iteration 32, task: 16, thread: 3
beginning iteration 15, task: 24, thread: 10
beginning iteration 36, task: 22, thread: 7
beginning iteration 33, task: 16, thread: 3
completed iteration 57, task: 17, thread: 5
beginning iteration 58, task: 17, thread: 5
completed iteration 7, task: 1, thread: 1
beginning iteration 8, task: 1, thread: 1
completed iteration 11, task: 18, thread: 6
beginning iteration 12, task: 18, thread: 6
completed iteration 80, task: 19, thread: 4
beginning iteration 81, task: 19, thread: 4
completed iteration 39, task: 20, thread: 11
beginning iteration 64, task: 23, thread: 12
beginning iteration 40, task: 27, thread: 11
completed iteration 84, task: 21, thread: 9
completed iteration 60, task: 25, thread: 8
beginning iteration 61, task: 25, thread: 8
completed iteration 36, task: 22, thread: 7
beginning iteration 37, task: 22, thread: 7
beginning iteration 85, task: 28, thread: 9
completed iteration 15, task: 24, thread: 10
completed iteration 33, task: 16, thread: 3
beginning iteration 34, task: 16, thread: 3
beginning iteration 16, task: 24, thread: 10
completed iteration 58, task: 17, thread: 5
beginning iteration 59, task: 17, thread: 5
completed iteration 8, task: 1, thread: 1
beginning iteration 9, task: 1, thread: 1
completed iteration 12, task: 18, thread: 6
beginning iteration 13, task: 18, thread: 6
completed iteration 81, task: 19, thread: 4
beginning iteration 82, task: 19, thread: 4
beginning iteration 89, task: 26, thread: 13
completed iteration 64, task: 23, thread: 12
beginning iteration 65, task: 30, thread: 12
*breaking iteration 40, task: 27, thread: 11 //下面将不会出现index>40的迭代(61,85,59,82,89,65都是之前启动的,不受影响,继续执行)
completed iteration 40, task: 27, thread: 11
completed iteration 61, task: 25, thread: 8
completed iteration 85, task: 28, thread: 9
completed iteration 34, task: 16, thread: 3
completed iteration 37, task: 22, thread: 7
completed iteration 16, task: 24, thread: 10
beginning iteration 17, task: 35, thread: 10
beginning iteration 38, task: 22, thread: 7
completed iteration 59, task: 17, thread: 5
completed iteration 9, task: 1, thread: 1
beginning iteration 21, task: 1, thread: 1
completed iteration 13, task: 18, thread: 6
completed iteration 82, task: 19, thread: 4
completed iteration 89, task: 26, thread: 13
completed iteration 65, task: 30, thread: 12
completed iteration 17, task: 35, thread: 10
completed iteration 38, task: 22, thread: 7
beginning iteration 18, task: 35, thread: 10
completed iteration 21, task: 1, thread: 1
beginning iteration 22, task: 1, thread: 1
completed iteration 18, task: 35, thread: 10
beginning iteration 19, task: 35, thread: 10
completed iteration 22, task: 1, thread: 1
beginning iteration 23, task: 1, thread: 1
completed iteration 19, task: 35, thread: 10
beginning iteration 20, task: 35, thread: 10
completed iteration 23, task: 1, thread: 1
beginning iteration 24, task: 1, thread: 1
completed iteration 20, task: 35, thread: 10
completed iteration 24, task: 1, thread: 1
False
lowest break iteration: 40
示例2 if(i >=40)的执行结果
beginning iteration 0, task: 1, thread: 1
beginning iteration 25, task: 2, thread: 3
beginning iteration 50, task: 3, thread: 5
beginning iteration 75, task: 4, thread: 4
beginning iteration 1, task: 5, thread: 6
beginning iteration 26, task: 6, thread: 7
completed iteration 0, task: 1, thread: 1
beginning iteration 2, task: 1, thread: 1
completed iteration 25, task: 2, thread: 3
*breaking iteration 50, task: 3, thread: 5 //下面将不会有index>50的迭代运行(注意已经启动的不受影响)
completed iteration 50, task: 3, thread: 5
*breaking iteration 75, task: 4, thread: 4 //下面将不会有index>50(因为75>50,用最小的)的迭代运行
completed iteration 75, task: 4, thread: 4
beginning iteration 27, task: 8, thread: 3
completed iteration 1, task: 5, thread: 6
beginning iteration 4, task: 11, thread: 4
completed iteration 26, task: 6, thread: 7
beginning iteration 29, task: 12, thread: 5
completed iteration 2, task: 1, thread: 1
beginning iteration 3, task: 1, thread: 1
completed iteration 27, task: 8, thread: 3
beginning iteration 28, task: 8, thread: 3
completed iteration 4, task: 11, thread: 4
beginning iteration 5, task: 11, thread: 4
completed iteration 29, task: 12, thread: 5
beginning iteration 30, task: 12, thread: 5
completed iteration 3, task: 1, thread: 1
beginning iteration 6, task: 1, thread: 1
completed iteration 28, task: 8, thread: 3
beginning iteration 31, task: 13, thread: 3
completed iteration 5, task: 11, thread: 4
beginning iteration 10, task: 14, thread: 4
completed iteration 30, task: 12, thread: 5
beginning iteration 35, task: 15, thread: 6
completed iteration 6, task: 1, thread: 1
beginning iteration 7, task: 1, thread: 1
completed iteration 31, task: 13, thread: 3
beginning iteration 32, task: 13, thread: 3
completed iteration 10, task: 14, thread: 4
beginning iteration 11, task: 14, thread: 4
completed iteration 35, task: 15, thread: 6
beginning iteration 36, task: 15, thread: 6
completed iteration 7, task: 1, thread: 1
beginning iteration 8, task: 1, thread: 1
completed iteration 32, task: 13, thread: 3
beginning iteration 33, task: 13, thread: 3
completed iteration 11, task: 14, thread: 4
beginning iteration 12, task: 14, thread: 4
completed iteration 36, task: 15, thread: 6
beginning iteration 37, task: 15, thread: 6
completed iteration 8, task: 1, thread: 1
beginning iteration 9, task: 1, thread: 1
completed iteration 33, task: 13, thread: 3
beginning iteration 34, task: 13, thread: 3
completed iteration 12, task: 14, thread: 4
beginning iteration 13, task: 14, thread: 4
completed iteration 37, task: 15, thread: 6
beginning iteration 38, task: 15, thread: 6
completed iteration 9, task: 1, thread: 1
beginning iteration 14, task: 1, thread: 1
completed iteration 34, task: 13, thread: 3
beginning iteration 39, task: 16, thread: 5
completed iteration 13, task: 14, thread: 4
beginning iteration 22, task: 17, thread: 3
completed iteration 38, task: 15, thread: 6
beginning iteration 47, task: 18, thread: 4
completed iteration 14, task: 1, thread: 1
beginning iteration 15, task: 1, thread: 1
completed iteration 39, task: 16, thread: 5
beginning iteration 40, task: 16, thread: 5
completed iteration 22, task: 17, thread: 3
beginning iteration 23, task: 17, thread: 3
*breaking iteration 47, task: 18, thread: 4 //下面将不会有index>47(因为47<50,用最小的)的迭代运行
completed iteration 47, task: 18, thread: 4
completed iteration 15, task: 1, thread: 1
beginning iteration 16, task: 1, thread: 1
*breaking iteration 40, task: 16, thread: 5 //下面将不会有index>40(因为40<47,用最小的)的迭代运行
completed iteration 40, task: 16, thread: 5
completed iteration 23, task: 17, thread: 3
beginning iteration 24, task: 17, thread: 3
completed iteration 16, task: 1, thread: 1
beginning iteration 17, task: 1, thread: 1
completed iteration 24, task: 17, thread: 3
completed iteration 17, task: 1, thread: 1
beginning iteration 18, task: 1, thread: 1
completed iteration 18, task: 1, thread: 1
beginning iteration 19, task: 1, thread: 1
completed iteration 19, task: 1, thread: 1
beginning iteration 20, task: 1, thread: 1
completed iteration 20, task: 1, thread: 1
beginning iteration 21, task: 1, thread: 1
completed iteration 21, task: 1, thread: 1
False
lowest break iteration: 40
示例3
///
/// 特别注意一个线程可能被多个迭代使用
///
public static void ThreadDemo3()
{
Parallel.For<string>(0, 6, () => {
//初始化线程,注意线程数可能少于迭代数
var val1 = String.Format("init ({0} {1})", Thread.CurrentThread.ManagedThreadId, Task.CurrentId);
System.Diagnostics.Debug.WriteLine(val1);
return val1;
},
(i, pls, str) => {//线程数少于迭代数时,表面多个迭代使用了同一个线程
var val2 = String.Format("body i={0} ({1} {2}), str=[{3}]",
i, Thread.CurrentThread.ManagedThreadId, Task.CurrentId, str);
System.Diagnostics.Debug.WriteLine(val2);
return val2;
},
(str1) => {//线程结束时扫尾,注意线程数少于迭代数的情况
var val3 = String.Format("fina ({0} {1}), str1=[{2}]", Thread.CurrentThread.ManagedThreadId, Task.CurrentId, str1);
System.Diagnostics.Debug.WriteLine(val3);
});
}
执行结果如下
init (3 2)
init (1 1)
init (4 3)
body i=2 (4 3), str=[init (4 3)]
body i=0 (1 1), str=[init (1 1)]
body i=5 (4 3), str=[body i=2 (4 3), str=[init (4 3)]]
body i=1 (3 2), str=[init (3 2)]
init (6 5)
init (5 4)
body i=4 (6 5), str=[init (6 5)]
fina (6 5), str1=[body i=4 (6 5), str=[init (6 5)]]
fina (4 3), str1=[body i=5 (4 3), str=[body i=2 (4 3), str=[init (4 3)]]]
fina (3 2), str1=[body i=1 (3 2), str=[init (3 2)]]
body i=3 (5 4), str=[init (5 4)]
fina (5 4), str1=[body i=3 (5 4), str=[init (5 4)]]
fina (1 1), str1=[body i=0 (1 1), str=[init (1 1)]]
//把上面结果整理一下,便于看清:
init (3 2)
body i=1 (3 2), str=[init (3 2)]
fina (3 2), str1=[body i=1 (3 2), str=[init (3 2)]]
init (1 1)
body i=0 (1 1), str=[init (1 1)]
fina (1 1), str1=[body i=0 (1 1), str=[init (1 1)]]
init (4 3) //迭代i=2, i=5公用线程
body i=2 (4 3), str=[init (4 3)]
body i=5 (4 3), str=[body i=2 (4 3), str=[init (4 3)]]
fina (4 3), str1=[body i=5 (4 3), str=[body i=2 (4 3), str=[init (4 3)]]]
init (6 5)
body i=4 (6 5), str=[init (6 5)]
fina (6 5), str1=[body i=4 (6 5), str=[init (6 5)]]
init (5 4)
body i=3 (5 4), str=[init (5 4)]
fina (5 4), str1=[body i=3 (5 4), str=[init (5 4)]]
示例4
///
/// Parallel.ForEach实现了遍历IEnumerable的集合
///
public static void ThreadDemo4()
{
string[] data = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
ParallelLoopResult result = Parallel.ForEach<string>(data, stringItem => {
System.Diagnostics.Debug.WriteLine("thread={0}, task={1}, data={2}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId, stringItem);
});
}
示例5 - 消息线程
public static void ThreadDemo5()
{
var cts = new CancellationTokenSource();
cts.Token.Register(() => {//取消操作时调用的委托
System.Diagnostics.Debug.WriteLine("callback: token canceled");
});
//1s后取消
new Task(()=> {
Thread.Sleep(1000);
cts.Cancel(false);
}).Start();
try
{
ParallelLoopResult ret = Parallel.For(0, 100,
new ParallelOptions() { CancellationToken = cts.Token },
x => {
System.Diagnostics.Debug.WriteLine("iteration = {0,3} started", x);
int sum = 0;
for(int i=0; i<100; ++i)
{
Thread.Sleep(10);
sum += i;
}
System.Diagnostics.Debug.WriteLine("iteration = {0,3} finished", x);
});
}//一旦取消操作,For()方法就会抛出OperationCanceledException
catch (OperationCanceledException ex)
{
System.Diagnostics.Debug.WriteLine("canceled exception: " + ex.Message);
}
}
执行结果如下:
iteration = 50 started
iteration = 0 started
iteration = 75 started
iteration = 25 started
iteration = 1 started
callback: token canceled
iteration = 0 finished
iteration = 50 finished
iteration = 25 finished
iteration = 75 finished
iteration = 1 finished
Exception thrown: 'System.OperationCanceledException' in mscorlib.dll
canceled exception: 已取消该操作。