线程
进程与线程
看下任务管理器的线程数
1.线程之间可以数据共享
2.线程是切换执行的
创建线程 第一种方法,无返回值
语法:var task = new Task(…);
注意 task.start() task.Wait()
//说明一下何谓线程共享数据
//进程线程
//创建线程 第一种方法,无返回值
//var task = new Task(..);
//注意 task.start() task.Wait()
//说明一下何谓线程共享数据
int times = 5000;
var task1 = new Task(() =>
{
for (int i = 0; i < times; i++)
{
Console.Write(".");
}
});
var task2 = new Task(() =>
{
for (int i = 0; i < times; i++)
{
Console.Write("-");
}
});
task1.Start();
task2.Start();
task2.Wait();
task2.Wait();
Console.Read();
创建线程 第二种方法,可有可无 返回值
语法:var tast=Task.Factory.StartNew(…);
注:Task.Result 会阻塞
直接执行,无需Start()
var task = Task.Factory.StartNew(() => "进程");
Console.WriteLine(task.Result);
线程上的异常处理方法
方法一
Try 下面的语句,即可捕获
task.Wait()
task.Result();
task.WaitAll()
task.WaitAny();
var task = Task.Factory.StartNew(() => throw new ApplicationException("here is an erro")); ;
try
{
task.Wait();
}
catch (AggregateException exs)
{
foreach (var ex in exs.InnerExceptions)
{
Console.WriteLine(ex.Message);
}
}
方法二
线程上的异常处理方法二。
使用task.ContinueWith(…)
var task = Task.Factory.StartNew(() => throw new ApplicationException("here is an erro")); ;
task.ContinueWith((t) => { Console.WriteLine(t.Exception); },TaskContinuationOptions.OnlyOnFaulted);
并行处理
Parallel.For()
Parallel.ForEach()
PLINQ–x.Asparallel().X
static void Main(string[] args) //主线程
{
var list = new List<int>();
for (int i = 0; i < 50000000; i++)
{
list.Add(i);
}
CalcTime(() => list.ForEach(i =>Do(ref i)));
CalcTime(() => list.AsParallel().ForAll(i => Do(ref i)));
CalcTime(() => Parallel.ForEach(list,i=> Do(ref i) ));
//task2.Wait();
//task2.Wait();
Console.Read();
}
static void Do(ref int i) {
i = (int)Math.Abs(Math.Sin((i)));
}
static void CalcTime(Action action) {
Stopwatch sw = new Stopwatch();
sw.Start();
action();
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
同步
作用:
原子性
线程安全
class Program
{
static int Count = 0;
static void Main(string[] args) //主线程
{
var task1 = new Task(Increment);
var task2 = new Task(Decrement);
task1.Start();
task2.Start();
Task.WaitAll(task1, task2);
Console.WriteLine(Count);
Console.Read();
}
static void Increment() {
for (int i = 0; i < 5000000; i++)
{
Count++;
}
}
static void Decrement() {
for (int i = 0; i < 5000000; i++)
{
Count--;
}
}
使用Lock 关键字
使的操作育有原子性
最佳实践
1.对可变的状态进行同步
2.不更改东西不需要同步
3.多个线程访问同一对象是,必须
class Program
{
static int Count = 0;
private static readonly object Syn = new object();
static void Main(string[] args) //主线程
{
var task1 = new Task(Increment);
var task2 = new Task(Decrement);
task1.Start();
task2.Start();
Task.WaitAll(task1, task2);
Console.WriteLine(Count);
Console.Read();
}
static void Increment() {
for (int i = 0; i < 50000000; i++)
{
lock (Syn) //锁
{
Count++;
}
}
}
static void Decrement() {
for (int i = 0; i < 50000000; i++)
{
lock (Syn)
{
Count--;
}
}
原子操作
简单封装
interlocked
class Program
{
static int Count = 0;
static void Main(string[] args) //主线程
{
var task1 = new Task(Increment);
var task2 = new Task(Decrement);
task1.Start();
task2.Start();
Task.WaitAll(task1, task2);
Console.WriteLine(Count);
Console.Read();
}
static void Increment() {
for (int i = 0; i < 50000000; i++)
{
Interlocked.Increment(ref Count);
}
}
static void Decrement() {
for (int i = 0; i < 50000000; i++)
{
Interlocked.Decrement(ref Count);
}
}
IOC控制反转/DIP 依赖倒置
说白了,面向接口编程…
以来抽象的世界,很美妙…
随后举例–策略模式
先不面相接口,再面向接口
class Button {
public void On() {
Console.WriteLine("On");
}
public void Off()
{
Console.WriteLine("Off");
}
}
class Lamp {
private Button button = new Button();//has-a
public void on() { button.On(); }
public void Off() { button.Off(); }
}
interface IButton {
void On();
void Off();
}
class Program
{
class Button: IButton
{
public void On() {
Console.WriteLine("On");
}
public void Off()
{
Console.WriteLine("Off");
}
}
class Lamp {
private IButton button;
public Button Button { get; set; }
public void on() { button.On(); }
public void Off() { button.Off(); }
}
static void Main(string[] args) //主线程
{
var lamp = new Lamp() { Button = new Button() };
;
Console.WriteLine(Guid.NewGuid().ToString("D"));
}