进程 Process

包含多个线程 Thread

指令:方法(委托)
数据:相关对象

Thread 属性

  • CurrentPrincipal 当前线程安全性
  • CurrentThread
  • IsAlive
  • IsBackground
  • Name
  • Priority 线程优先级
  • ThreadState 当前状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System;
using System.Threading;
class Test
{
static void Main()
{
Test obj1 = new Test();
Thread thread1 = new Thread( new ThreadStart( obj1.Count ));
thread1.Name = "线程1";
Test obj2 = new Test();
Thread thread2 = new Thread( new ThreadStart( obj2.Count ));
thread2.Name = "线程2";
Thread thread3 = new Thread( new ThreadStart( obj2.Count ));
thread3.Name = "线程3";
thread1.Start();
thread2.Start();
thread3.Start();
}
private int cnt = 0;

private void Count()
{
while( cnt < 10 )
{
cnt ++;
Console.WriteLine( Thread.CurrentThread.Name + "数到" + cnt );
Thread.Sleep( 100 );
}
}
}

Thread 方法

  • Abort 撤销
  • Interrupt 中断
  • Join 等待
  • Resume 恢复
  • Sleep
  • Start
  • Suspend 挂起

ThreadState Enume

  • Aborted
  • AbortedRequested
  • Background
  • Running
  • Stopped
  • StopRequested
  • Suspended
  • SuspendRequested
  • Unstarted
  • WaitSleepJoin

ThreadPriority

  • Highest
  • AboveNormal
  • Normal
  • BelowNormal
  • Lowest

线程同步

Join()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class ThreadJoin {
public static void Main(string [] args) {
Runner r = new Runner();
Thread thread = new Thread( r.run );
thread.Start();
thread.Join();
for( int i=0; i<10; i++ ){
Console.WriteLine("\t" + i );
Thread.Sleep(100);
}
}
}

class Runner {
public void run() {
for( int i=0; i<10; i++ ){
Console.WriteLine( i );
Thread.Sleep(100);
}
}
}

多线程访问同变量

Lock(对象,表达式){

}

System.Threading.Monitor.Enter(对象,表达式);
System.Threading.Monitor.Exit(对象,表达式);

线程池

Threadpool.QueueUserWorkItem(WaitCallback, object)

Timer(TimerCallback callback, //执行的任务
object state, //数据
int dueTime, //启动前的延时
int period //任务间隔
)

线程安全

IsSynchoronized() 判断是否为同步
SyncRoot()
Synchronized()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using System;
using System.Collections;
public class SamplesArrayList {
public static void Main() {
ArrayList myAL = new ArrayList();
myAL.Add( "The" );
myAL.Add( "quick" );
myAL.Add( "brown" );
myAL.Add( "fox" );
ArrayList mySyncdAL = ArrayList.Synchronized( myAL );
Console.WriteLine( myAL.IsSynchronized ); //False
Console.WriteLine( mySyncdAL.IsSynchronized ); //True
}
}

并行编程

TPL 并行任务库

Task 类,利用线程池进行任务执行
Parallel 类,并行执行任务类的实用类,隐式的使用Task

使用方法:
Task task = Task.Run(()=> someFun());
double res = task.Result;
Task.WaitAll
task.ContinueWith

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
class T
{
static void Main(string[] args)
{
Task<double>[] tasks = {
Task.Run( ()=>SomeFun() ),
Task.Run( ()=>SomeFun() ),
};
Thread.Sleep(1);
for(int i=0; i<tasks.Length; i++ )
{
Console.WriteLine(tasks[i].Status); //可以查看状态
Console.WriteLine(tasks[i].Result); //取Result时,会等到计算结束
}
Task.WaitAll( tasks ); //也可以用这句,来等结束
}
static void DoSometing(){}
static double SomeFun(){ Thread.Sleep(50); return 0; }
}

异常处理:AggregateExecption(合并的异常)

使用方法:
Parallel.Invoke(Action[] actions)
Parallel.For(0, 100, i=>{})
Parallel.FOrEach(list, item=>{})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Threading;
using System.Threading.Tasks;
class TestParallelInvoke
{
static void Main(string[] args)
{
Action[] actions = { new Action(DoSometing), DoSometing };
Parallel.Invoke( actions );
Console.WriteLine("主函数所在线程"+Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
static void DoSometing(){
Console.WriteLine("函数所在线程"+Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
}
}

class T
{
static void Main(string[] args)
{
Parallel.For(0, 10, i =>
{
Console.WriteLine("i={0}, fac={1}, 线程id={2}", i, Calc(i),
Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(10);
});
Console.ReadLine();
}
static double Calc(int n)
{
double f = 1;
for(int i=1; i<=n; i++ ) f*=i;
return f;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
class T
{
static void Main(string[] args)
{
List<double> list = new List<double>();
for(int i=0; i<100; i++) list.Add(i*i);
ParallelLoopResult loopResult = Parallel.ForEach(
list, (double x, ParallelLoopState state) =>
{
if (x == 400)state.Break();
Console.WriteLine("x={0},thread id={1}", x, Thread.CurrentThread.ManagedThreadId);
});
Console.WriteLine("IsCompleted: {0}",
loopResult.IsCompleted);
Console.WriteLine("BreakValue: {0}",
loopResult.LowestBreakIteration.HasValue);
Console.ReadLine();
}
}

Linq,PLinq

使用方法:
使用Linq语法,集合.AsParallel()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
class Program {
const int count = 1000000;
static void Main(string[] args) {
var dic = LoadData();
Stopwatch watch = new Stopwatch();
watch.Start();
//串行运算
var query1 = (from n in dic.Values
where n.Age > 20 && n.Age < 25
select n).ToList();
watch.Stop();
Console.WriteLine("串行计算耗费时间:{0}", watch.ElapsedMilliseconds);
watch.Restart();
//并行运算
var query2 = (from n in dic.Values.AsParallel()
where n.Age > 20 && n.Age < 25
select n).ToList();
watch.Stop();
Console.WriteLine("并行计算耗费时间:{0}", watch.ElapsedMilliseconds);
Console.Read();
}
public static ConcurrentDictionary<int, Student> LoadData() {
ConcurrentDictionary<int, Student> dic =
new ConcurrentDictionary<int, Student>();
Parallel.For(0, count, (i) => {
var single = new Student() {
ID = i,
Name = "n" + i,
Age = i % 151,
//CreateTime = DateTime.Now.AddSeconds(i)
};
dic.TryAdd(i, single);
});
return dic;
}
public class Student {
public int ID {get;set;}
public string Name {get;set;}
public int Age {get;set;}
public DateTime CreateTime {get;set;}
}
}

异步编程

asynchronize

主要解决的事情:
等待一些耗时的任务,不阻塞当前任务
异步提高UI响应能力

  • 方法一 委托
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

/// <summary>
/// 异步调用方法总结:
/// 1.BeginEnvoke EndEnvoke
/// 当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕
/// </summary>
class Async1
{
public delegate int FooDelegate(string s);
static void Main(string[] args)
{
Console.WriteLine("主线程"+Thread.CurrentThread.ManagedThreadId);
FooDelegate fooDelegate = Foo;
IAsyncResult result= fooDelegate.BeginInvoke("Hello World.", null, null);
Console.WriteLine("主线程继续执行...");
//当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕
int n = fooDelegate.EndInvoke(result);
Console.WriteLine("回到主线程"+Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("结果是"+n);
Console.ReadKey(true);
}
public static int Foo(string s)
{
Console.WriteLine("函数所在线程"+Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("异步线程开始执行:"+s);
Thread.Sleep(1000);
return s.Length;
}
}
  • 方法二 回调
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

/// <summary>
/// 异步调用方法总结:
/// 回调
/// 异步线程在工作结束后会主动调用我们提供的回调方法,并在回调方法中做相应的处理,例如显示异步调用的结果。
/// </summary>

class Program
{
public delegate void FooDelegate(string s);
static void Main(string[] args)
{
Console.WriteLine("主线程."+Thread.CurrentThread.ManagedThreadId);
FooDelegate fooDelegate = Foo;
fooDelegate.BeginInvoke("Hello world.",
FooComepleteCallback, fooDelegate);
Console.WriteLine("主线程继续执行..."+Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Press any key to continue...");
Console.ReadKey(true);
}
public static void Foo(string s)
{
Console.WriteLine("函数当前线程:"+Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(s);
Thread.Sleep(1000);
}

//回调方法要求
//1.返回类型为void
//2.只有一个参数IAsyncResult
public static void FooComepleteCallback(IAsyncResult result)
{
Console.WriteLine("回调函数所在线程:"+Thread.CurrentThread.ManagedThreadId);
(result.AsyncState as FooDelegate).EndInvoke(result);
Console.WriteLine("回调函数线程结束." + result.AsyncState.ToString());
}
}
  • 方法三 await async

await 等待任务执行
async 修饰符,内部存在异步任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Threading;
using System.Threading.Tasks;
class AsyncSimple1
{
Task<double> FacAsync(int n)
{
return Task<double>.Run( ()=>{
double s = 1;
for(int i=1; i<n; i++) s = s*i;
return s;
});
}
async void Test()
{
// 调用异步方法
double result = await FacAsync(10);
Console.WriteLine( result); //想想这句在哪个线程
}
static void Main()
{
new AsyncSimple1().Test();
Console.ReadKey();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Threading;
using System.Threading.Tasks;
using System.IO;
public class AsyncStream
{
async Task<int> WriteFile()
{
using (StreamWriter sw = new StreamWriter(
new FileStream("aaa.txt", FileMode.Create) ))
{
await sw.WriteAsync("my text");
return 1;
}
}
async static void Test()
{
AsyncStream a = new AsyncStream();
await a.WriteFile();
Console.WriteLine("Write OK");
}
static void Main()
{
Test();
}
}