这四个都是异步线程。
delegate和event,属于基础库。
thread-using system.threading
task-using system.threading.task
thread 和 task不常用了,主要应用 delegate和event
异步线程就是在程序的主线程之外在创建一个子线程执行,线程之间执行相互不想干,主线程并不需要要等待子线程的执行,就是相当于跑步比赛一样,各个赛道中的人同时进行奔跑。
多线程概念之中还有一个同步线程,其实就是将多个线程包装成一个模块,依次执行,就相当于有很多条赛道,第一条赛道中的人跑完,第二条赛道中的人继续奔跑,依次执行。
本人还没有还没有用过同步线程,一开始觉得为何要有同步线程这个东西呢?为何不用单线程呢?其实任何一件产品被人广泛的使用都有它一定的道理,后来经过大脑一思考,终于被我想到了。如果我们创建了过多的异步线程是不是会造成服务器的开销很大呢?创建的线程大于了服务器的开销,反而会导致线程的之间的切换过于的平凡,反而会降低程序运行的效率,有可能还会导致出现异常,这样的话使用多线程是不是没有意义了呢?这个之后我们是不是可以采用同步线程来管理异步线程呢?当然以上只是我个人的观点,并没有经过实际的验证。
1、thread
原始线程,缺点:创建多线的时候如果手动.Abort()的话,如果此线程正在执行状态中,强制关闭则会抛出异常。还用可能会把主线程也给卡死。
使用格式(4种):
普通多线程,需调用方法
Thread thread1 = new Thread(Run);
//Thread thread1 = new Thread(new ThreadStart(Run));
thread1.Start();
使用匿名方法(使用匿名方法,需要加入delegate(){})
Thread thread2 = new Thread(delegate()
//Thread thread2 = new Thread(new ThreadStart(delegate()
//Thread thread2 = new Thread(new ThreadStart(delegate
{do something
});
thread2.Start();
使用Lambda表达式(Lamda表达式只是将一些多余的词汇省略掉。但是VS2005不支持这种格式,.NET 3.0以上才能使用Lamda表达式,3.5以后才能使用Action)
Thread thread3=new Thread(()=>
//Thread thread3=new Thread(new ThreadStart(()=>
{
});
如果省略前面的Thread thread3=,那么就可以使用如下格式:将.Start();追加在最后
new Thread(delegate()
//new Thread(new ThreadStart(delegate
{do something
}).Start();
2、task
Task和thread本身没有多大区别,无非就是语法的不同摆了,Task的方式也就是相当于创建了一个新的线程,task.Result等待这个线程执行完返回的结果。
使用格式(3种):
Task.Factory.StartNew(new Action(() =>
));
var task=Task.Factory.StartNew(()=>
{
},TaskCreationOptions.LongRunning);
Task task = Task.Factory.StartNew(() =>
{
//从线程
}).ContinueWith((t) =>
{
//从线程执行完后,回到主线程执行这部分
//但是!可以调用从线程里的内容
}, TaskScheduler.FromCurrentSynchronizationContext());
3、delegate
是thread的升级,现在多使用delegate,少使用thread。
使用方式(较多):
class Program
{
private delegate void FlushClient(Action action, int timers);
static void Main(string[] args)
{
int timers = 10;
FlushClient fc = new FlushClient(ThreadFunction);
fc.BeginInvoke(fun, timers, null, null);
}
static void fun() { }
private static void ThreadFunction(Action action, int timers)
{
action();
Thread.Sleep(timers * 1000);
}
}
---------------------------------------------------------------------
public delegate void delegateName(string str);//在类外定义委托
class Program
{
private static void A(string str)
{
Console.WriteLine("A" + str);
}
private static void B(string str)
{
Console.WriteLine("B" + str);
}
private static void ALL(string str, delegateName funName)
{
funName(str);
}
static void Main(string[] args)
{
ALL("1", A);
ALL("2", B);
Console.ReadLine();
}
}
---------------------------------------------------------------------
public delegate void delegateName(string str);//在类外定义委托
class Program
{
private static void A(string str)
{
Console.WriteLine("A" + str);
}
private static void B(string str)
{
Console.WriteLine("B" + str);
}
static void Main(string[] args)
{
delegateName delegate1 = new delegateName(A);//声明+初始化
delegate1 += B;
delegate1("1");
delegate1 -= A;
delegate1("2");
Console.ReadLine();
}
}
---------------------------------------------------------------------
class Program
{
public delegate void D(string str);
static void Main(string[] args)
{
D delegate1 = new D(B);
delegate1+=AF.A;
delegate1("HaHa");
System.Threading.Thread.Sleep(100000);
}
public static void B(string str)
{
Console.WriteLine(str);
}
}
class AF
{
public static void A(string str){//必须是public才能被class Program 访问
Console.WriteLine(str);
}
---------------------------------------------------------------------
class Program
{
public delegate void delegateName(string str);
static void Main(string[] args)
{
delegateName delegate1 = delegate(string str)
{
Console.WriteLine("A" + str);
};
//或者
//简化:利用Lamdba表达式,加了一个(); 和=>,省去了delegate
delegateName delegate1 = ((string str)=>{
Console.WriteLine("A" + str);
});
delegate1 += delegate(string str)
{
Console.WriteLine("B" + str);
};
delegate1("1");
Console.ReadLine();
}
}
---------------------------------------------------------------------
加返回值,将void 改为 string
class Program
{
public delegate string delegateName(string str);
static void Main(string[] args)
{
delegateName delegate1 = delegate(string str)
{
Console.WriteLine("A" + str);
return "1";
};
//或者
//简化:利用Lamdba表达式,加了一个(); 和=>,省去了delegate
delegateName delegate1 = ((string str)=>{
Console.WriteLine("A" + str);
});
delegate1 += delegate(string str)
{
Console.WriteLine("B" + str);
return "2";
};
string receive=delegate1("1");
Console.ReadLine();
}
}
---------------------------------------------------------------------
class Program
{
static void Main(string[] args)
{
Func<int, int, string> function = ((int a, int b) =>
{
if (a == 1) return "a";
else if (b == 1) return "b";
else return " ";
});
string result = function(3, 3);
}
}
class Program
{
static void Main(string[] args)
{
Action<int , int> function = (( int a , int b)=> { });
function(3, 3);
}
}
---------------------------------------------------------------------
class Program
{
static void Main(string[] args)
{
Predicate<int> function =(( int a ) =>
{
return true;
}
);
bool result = function(3);
}
}
---------------------------------------------------------------------
等价于
class Program
{
static void Main(string[] args)
{
Predicate<int> function = Function;
bool result = function(3);
}
public static bool Function(int a)
{
return true;
}
}
4、event
是对delegate的封装,是对thread的一种优化。
在.net 4.0之后提出“任务的编程模型“,task会比thread具有更小的性能开销,
1、任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执行。
2、任务跟线程不是一对一的关系,比如开10个任务并不是说会开10个线程,这一点任务有点类似线程池,但是任务相比线程池有很小的开销和精确的控制。
使用方法:
分为两块,事件发生类和事件接收处理类
事件发生类:
public EventHandler<AsyncPaintEventArgs> AsyncPaint;
AsyncPaint += beforeDisplayImage;
this.imageSize = imageSize;
if (AsyncPaint != null)
{
var args = new AsyncPaintEventArgs
{
TaskimageDatas=imageDatas
};
AsyncPaint(this, args)
}
private void beforeDisplayImage(object sender, AsyncPaintEventArgs e)
{
//先做点什么
}
public class AsyncPaintEventArgs : EventArgs
{
public ushort[] TaskimageDatas { get; set; }
}
事件接收处理类:
g.AsyncPaint += ucImage1_AsyncPaint;
private void ucImage1_AsyncPaint(object sender, AsyncPaintEventArgs e)
{
if (e != null && e.TaskimageDatas != null)
{
}
}