Socket 多线程问题 多看看msdn上的例子,自己多做一些实验就明白了,不过socket编程我建议还是异步优先。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://topic.csdn.net/t/20040503/09/3029294.html看看上面那个讨论,很激烈的,搞的我也糊涂了高手在这个贴继续讨论 看到一篇文章http://blog.sina.com.cn/s/blog_5efecc7a0100foj8.html楼主可以看看我转到这里C# 同步异步的区别(2009-09-28 16:55:22)转载标签:杂谈 同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果异步方法则在被调用之后立即返回以便程序在被调用方法完成其任务的同时执行其它操作.NET框架基类库中有好几种类都可以提供同步和异步的方法调用。因为同步方法调用会导致程序流程中途等待,所以采用同步方法的情况下往往会导致程序执行的延迟相比来说,在某些条件下选择异步方法调用就可能更好一些例如,有的时候程序需要给多个Web服务发出请求,还有远程处理信道(HTTP、TCP)和代理,这时就最好采用异步方法.NET Framework允许异步调用任何方法,定义与需要调用的方法具有相同签名的委托CLR将自动为该委托定义添加适当签名的BeginInvoke虚方法和EndInvoke虚方法和Invoke方法。我们先来了解这2个方法和一个委托和一个接口:(1)BeginInvoke方法用于启动异步调用它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数,将 AsyncCallback 和 AsyncState(可通过 IAsyncResult 接口的AsyncState 属性获得)作为最后两个参数,如没有可以为空.BeginInvoke立即返回,不等待异步调用完成。BeginInvoke返回IasyncResult,可用于监视调用进度。结果对象IAsyncResult是从开始操作返回的,并且可用于获取有关异步开始操作是否已完成的状态。结果对象被传递到结束操作,该操作返回调用的最终返回值。在开始操作中可以提供可选的回调。如果提供回调,在调用结束后,将调用该回调;并且回调中的代码可以调用结束操作。(2)EndInvoke方法用于检索异步调用结果。在调用BeginInvoke后可随时调用EndInvoke方法,注意:始终在异步调用完成后调用EndInvoke.如果异步调用未完成,EndInvoke将一直阻塞到异步调用完成。EndInvoke的参数包括需要异步执行的方法的out和ref参数以及由BeginInvoke返回的IAsyncResult。要注意的是,始终在异步调用完成后调用EndInvoke(3)AsyncCallback委托用于指定在开始操作完成后应被调用的方法AsyncCallback委托被作为开始操作上的第二个到最后一个参数传递代码原型如下:[Serializable]public delegate void AsyncCallback(IAsyncResult ar);(4)IAsyncResult接口它表示异步操作的状态.该接口定义了4个公用属性实际上,发起和完成.NET异步调用有4种方案可供你选择1.方案1-自己调用EndInvoke方法异步执行方法的最简单方式是以BeginInvoke开始,对主线程执行一些操作,然后调用EndInvoke,EndInvoke直到异步调用完成后才返回还是先来段自己喜欢的控制台代码: 1using System; 2 3namespace ConsoleApplication1 4{ 5 class Class1 6 { 7 public delegate void AsyncEventHandler(); 8 9 void Event1()10 {11 Console.WriteLine("Event1 Start");12 System.Threading.Thread.Sleep(2000);13 Console.WriteLine("Event1 End");14 }1516 void Event2()17 {18 Console.WriteLine("Event2 Start");19 int i=1;20 while(i<1000)21 {22 i=i+1;23 Console.WriteLine("Event2 "+i.ToString());24 }25 Console.WriteLine("Event2 End");26 }2728 void CallbackMethod(IAsyncResult ar)29 {30 ((AsyncEventHandler) ar.AsyncState).EndInvoke(ar);31 }323334 [STAThread]35 static void Main(string[] args)36 {37 long start=0;38 long end=0;39 Class1 c = new Class1();40 Console.WriteLine("ready");41 start=DateTime.Now.Ticks;4243 AsyncEventHandler asy = new AsyncEventHandler(c.Event1);44 IAsyncResult ia=asy.BeginInvoke(null,null);45 c.Event2();46 asy.EndInvoke(ia);47 48 end =DateTime.Now.Ticks;49 Console.WriteLine("时间刻度差="+ Convert.ToString(end-start) );50 Console.ReadLine();51 }52 }53}54此程序简单,异步的处理过程在代码43-46这几行结果如下:现在让我们来看看同步处理修改代码43-46这几行代码:c.Event1();c.Event2();结果如下:前者的时间刻度大大小于后者我们可以明显地看到异步运行的速度优越性2.方案2-采用查询(IsCompleted属性)IAsyncResult.IsCompleted属性获取异步操作是否已完成的指示,发现异步调用何时完成.再次修改代码43-46这几行代码:AsyncEventHandler asy = new AsyncEventHandler(c.Event1);IAsyncResult ia=asy.BeginInvoke(null,null);c.Event2();while(!ia.IsCompleted){}asy.EndInvoke(ia);3.方案3-采用AsyncWaitHandle来等待方法调用的完成IAsyncResult.AsyncWaitHandle属性获取用于等待异步操作完成的WaitHandleWaitHandle.WaitOne方法阻塞当前线程,直到当前的WaitHandle收到信号使用WaitHandle,则在异步调用完成之后,但在通过调用EndInvoke结果之前,可以执行其他处理再次修改代码43-46这几行代码:AsyncEventHandler asy = new AsyncEventHandler(c.Event1);IAsyncResult ia=asy.BeginInvoke(null,null);c.Event2();ia.AsyncWaitHandle.WaitOne();4.方案4-利用回调函数如果启动异步调用的线程不需要处理调用结果,则可以在调用完成时执行回调方法要使用回调方法,必须将代表该方法的AsyncCallback委托传递给BeginInvoke再次修改代码43-46这几行代码:AsyncEventHandler asy = new AsyncEventHandler(c.Event1);asy.BeginInvoke(new AsyncCallback(c.CallbackMethod),asy);c.Event2(); 对于同步和异步,举个例子:例如QQ就是采用异步的,当你的好友不在线上时,你也可以给他发消息,而且一个QQ号可以同时接收多个好友发来的信息,这样就不阻塞;相反的,如果是同步,那你就必须得等你的好友在线时,才能和他聊天,而且由于同步阻塞,当有多个好友向你发信息时,你只能一个一个的接收。 C#.net 同步异步SOCKET通讯和多线程总结http://www.cnblogs.com/yuanermen/archive/2009/04/02/1428050.html这个总结得挺好,可以参考。 http://topic.csdn.net/u/20100603/11/8a9fdf23-3332-4757-a22c-0c9a81f1dbbb.html trackBar 控件的使用 正则表达式纠错,请各位多支持 请高手指点C#.NET怎么修改DLL文件 [C#] 怎么获取系统中的端口列表,并进行开启和关闭? oracle存储过程调用其他用户表 无法确定条件表达式的类型,因为“int”和“byte”可相互隐式转换 对于单双引号的用法还是不太懂 关于手机短信的问题? (分不够可以加) c# Windows Form遇到问题 C# 如何解析RDF 求助:加密前后的密码都知道,有谁知道加密方式 高分求救:DataTable转换成IList<T>
看看上面那个讨论,很激烈的,搞的我也糊涂了
高手在这个贴继续讨论
楼主可以看看
我转到这里
C# 同步异步的区别(2009-09-28 16:55:22)转载标签:杂谈 同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果
异步方法则在被调用之后立即返回以便程序在被调用方法完成其任务的同时执行其它操作.NET框架基类库中有好几种类都可以提供同步和异步的方法调用。
因为同步方法调用会导致程序流程中途等待,所以采用同步方法的情况下往往会导致程序执行的延迟
相比来说,在某些条件下选择异步方法调用就可能更好一些
例如,有的时候程序需要给多个Web服务发出请求,还有远程处理信道(HTTP、TCP)和代理,这时就最好采用异步方法.NET Framework允许异步调用任何方法,定义与需要调用的方法具有相同签名的委托
CLR将自动为该委托定义添加适当签名的BeginInvoke虚方法和EndInvoke虚方法和Invoke方法。我们先来了解这2个方法和一个委托和一个接口:
(1)BeginInvoke方法用于启动异步调用
它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数,将 AsyncCallback 和 AsyncState(可通过 IAsyncResult 接口的AsyncState 属性获得)作为最后两个参数,如没有可以为空.
BeginInvoke立即返回,不等待异步调用完成。
BeginInvoke返回IasyncResult,可用于监视调用进度。结果对象IAsyncResult是从开始操作返回的,并且可用于获取有关异步开始操作是否已完成的状态。
结果对象被传递到结束操作,该操作返回调用的最终返回值。
在开始操作中可以提供可选的回调。如果提供回调,在调用结束后,将调用该回调;并且回调中的代码可以调用结束操作。(2)EndInvoke方法用于检索异步调用结果。
在调用BeginInvoke后可随时调用EndInvoke方法,注意:始终在异步调用完成后调用EndInvoke.
如果异步调用未完成,EndInvoke将一直阻塞到异步调用完成。
EndInvoke的参数包括需要异步执行的方法的out和ref参数以及由BeginInvoke返回的IAsyncResult。
要注意的是,始终在异步调用完成后调用EndInvoke(3)AsyncCallback委托用于指定在开始操作完成后应被调用的方法
AsyncCallback委托被作为开始操作上的第二个到最后一个参数传递
代码原型如下:
[Serializable]
public delegate void AsyncCallback(IAsyncResult ar);(4)IAsyncResult接口
它表示异步操作的状态.
该接口定义了4个公用属性实际上,发起和完成.NET异步调用有4种方案可供你选择
1.方案1-自己调用EndInvoke方法
异步执行方法的最简单方式是以BeginInvoke开始,对主线程执行一些操作,然后调用EndInvoke,EndInvoke直到异步调用完成后才返回还是先来段自己喜欢的控制台代码: 1using System;
2
3namespace ConsoleApplication1
4{
5 class Class1
6 {
7 public delegate void AsyncEventHandler();
8
9 void Event1()
10 {
11 Console.WriteLine("Event1 Start");
12 System.Threading.Thread.Sleep(2000);
13 Console.WriteLine("Event1 End");
14 }
15
16 void Event2()
17 {
18 Console.WriteLine("Event2 Start");
19 int i=1;
20 while(i<1000)
21 {
22 i=i+1;
23 Console.WriteLine("Event2 "+i.ToString());
24 }
25 Console.WriteLine("Event2 End");
26 }
27
28 void CallbackMethod(IAsyncResult ar)
29 {
30 ((AsyncEventHandler) ar.AsyncState).EndInvoke(ar);
31 }
32
33
34 [STAThread]
35 static void Main(string[] args)
36 {
37 long start=0;
38 long end=0;
39 Class1 c = new Class1();
40 Console.WriteLine("ready");
41 start=DateTime.Now.Ticks;
42
43 AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
44 IAsyncResult ia=asy.BeginInvoke(null,null);
45 c.Event2();
46 asy.EndInvoke(ia);
47
48 end =DateTime.Now.Ticks;
49 Console.WriteLine("时间刻度差="+ Convert.ToString(end-start) );
50 Console.ReadLine();
51 }
52 }
53}
54此程序简单,异步的处理过程在代码43-46这几行
结果如下:
现在让我们来看看同步处理
修改代码43-46这几行代码:
c.Event1();
c.Event2();
结果如下:
前者的时间刻度大大小于后者
我们可以明显地看到异步运行的速度优越性2.方案2-采用查询(IsCompleted属性)
IAsyncResult.IsCompleted属性获取异步操作是否已完成的指示,发现异步调用何时完成.
再次修改代码43-46这几行代码:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
IAsyncResult ia=asy.BeginInvoke(null,null);
c.Event2();
while(!ia.IsCompleted)
{
}
asy.EndInvoke(ia);3.方案3-采用AsyncWaitHandle来等待方法调用的完成
IAsyncResult.AsyncWaitHandle属性获取用于等待异步操作完成的WaitHandle
WaitHandle.WaitOne方法阻塞当前线程,直到当前的WaitHandle收到信号
使用WaitHandle,则在异步调用完成之后,但在通过调用EndInvoke结果之前,可以执行其他处理
再次修改代码43-46这几行代码:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
IAsyncResult ia=asy.BeginInvoke(null,null);
c.Event2();
ia.AsyncWaitHandle.WaitOne();4.方案4-利用回调函数
如果启动异步调用的线程不需要处理调用结果,则可以在调用完成时执行回调方法
要使用回调方法,必须将代表该方法的AsyncCallback委托传递给BeginInvoke
再次修改代码43-46这几行代码:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
asy.BeginInvoke(new AsyncCallback(c.CallbackMethod),asy);
c.Event2();
例如QQ就是采用异步的,当你的好友不在线上时,你也可以给他发消息,而且一个QQ号可以同时接收多个好友发来的信息,这样就不阻塞;相反的,如果是同步,那你就必须得等你的好友在线时,才能和他聊天,而且由于同步阻塞,当有多个好友向你发信息时,你只能一个一个的接收。
http://www.cnblogs.com/yuanermen/archive/2009/04/02/1428050.html这个总结得挺好,可以参考。
http://topic.csdn.net/u/20100603/11/8a9fdf23-3332-4757-a22c-0c9a81f1dbbb.html