CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  .NET技术 >  .NET Framework

.net异步与多线程

楼主xiyou(溪游at福州)2006-09-19 14:25:28 在 .NET技术 / .NET Framework 提问

http://blog.csdn.net/xiyou/archive/2006/09/19/1245614.aspx  
  上面地址看的更清楚。  
   
  一直不清楚异步与多线程的区别,不知道回调函数是在新线程还是原线程执行。  
  上网没查找到,自已研究。  
   
  using   System;  
  using   System.IO;  
  using   System.Threading;  
  namespace   test_异步  
  {  
          class   Class1  
          {  
                  [STAThread]  
                  static   void   Main(string[]   args)  
                  {  
                          int   i=0;  
                          FileStream   fs=new   FileStream(@"c:kk.txt",FileMode.Create,FileAccess.Write,FileShare.Write);  
                          fs.BeginWrite(new   byte[]{1},0,1,new   AsyncCallback(endWrite),fs);  
                          while(true){  
                                  System.Console.WriteLine("main_"+i++);  
                                  Thread.Sleep(500);  
                          }  
                  }  
                  public   static   void   endWrite(IAsyncResult   ir)  
                  {  
                          ((FileStream)ir.AsyncState).Close();  
                          int   i=0;  
                          while(true)  
                          {  
                                  System.Console.WriteLine("endwrite_"+i++);  
                                  Thread.Sleep(100);  
                          }  
                  }  
          }  
  }  
    上面的结果是每输出5个   endwrite_i   输出一个   main_i   ,说明异步也是在不同线程中运行,和多线程没什么不同。  
  但是MSDN和网上的代码上很多代码都是在回调函数中再次调用异步函数,这样岂不是会产生很多进程?不过MSDN中都这样写也许不是这样,再次测试。  
   
  using   System;  
  using   System.IO;  
  using   System.Threading;  
  using   System.Runtime.InteropServices;  
   
  namespace   test_异步  
  {  
          class   Class1  
          {  
                  [DllImport("kernel32.dll")]      
                  public   static   extern   int   GetCurrentThreadId();      
                  [STAThread]  
                  static   void   Main(string[]   args)  
                  {  
                          int   i=0;  
                          FileStream   fs=new   FileStream(@"c:kk.txt",FileMode.Create,FileAccess.Write,FileShare.Write);  
                          fs.BeginWrite(new   byte[]{1},0,1,new   AsyncCallback(endWrite),fs);  
                          while(true){  
                                  System.Console.WriteLine("main_"+i++);  
                                  Thread.Sleep(100);  
                          }  
                  }  
                  public   static   void   endWrite(IAsyncResult   ir)  
                  {  
                          Thread.Sleep(100);  
                          ((FileStream)ir.AsyncState).Close();  
                          FileStream   fs=new   FileStream(@"c:kk.txt",FileMode.Create,FileAccess.Write,FileShare.Write);  
                          fs.BeginWrite(new   byte[]{1},0,1,new   AsyncCallback(endWrite),fs);  
                          System.Console.WriteLine("endwrite_"+GetCurrentThreadId());  
                  }  
          }  
  }  
  输出结果:  
   
   
     
   
  main_0  
  main_1  
  endwrite_2264  
  main_2  
  endwrite_2264  
  main_3  
  endwrite_2264  
  main_4  
  endwrite_2264  
  main_5  
  endwrite_2356  
  main_6  
  endwrite_2356  
  main_7  
  endwrite_2356  
  main_8  
  endwrite_2356  
  main_9  
  endwrite_2264  
  endwrite_2356  
  endwrite_2264  
  可以看到产生线程的ID多是相同的,是使用了同一个线程还是线程结束后,新线程ID号相同?再次测试。  
   
   
  using   System;  
  using   System.IO;  
  using   System.Threading;  
  using   System.Runtime.InteropServices;  
   
  namespace   test_异步  
  {  
          class   Class1  
          {  
                  [DllImport("kernel32.dll")]      
                  public   static   extern   int   GetCurrentThreadId();      
                  [STAThread]  
                  static   void   Main(string[]   args)  
                  {  
                          int   i=0;  
                          FileStream   fs=new   FileStream(@"c:kk.txt",FileMode.Create,FileAccess.Write,FileShare.Write);  
                          fs.BeginWrite(new   byte[]{1},0,1,new   AsyncCallback(endWrite),fs);  
                          while(i<100){  
                                  System.Console.WriteLine("main_"+i++);  
                                  Thread.Sleep(100);  
                          }  
                  }  
                  public   static   void   endWrite(IAsyncResult   ir)  
                  {  
                          ((FileStream)ir.AsyncState).Close();  
                          FileStream   fs=new   FileStream(@"c:kk.txt",FileMode.Create,FileAccess.Write,FileShare.Write);  
                          fs.BeginWrite(new   byte[]{1},0,1,new   AsyncCallback(endWrite),fs);  
                          System.Console.WriteLine("endwrite_"+GetCurrentThreadId());  
                          Thread.Sleep(100);  
                  }  
          }  
  }  
  结果输出:  
  …………  
  main_98  
  endwrite_2204  
  endwrite_3884  
  endwrite_2280  
  endwrite_2216  
  endwrite_1632  
  endwrite_740  
  endwrite_3760  
  endwrite_4016  
  endwrite_1220  
  endwrite_1784  
  endwrite_4088  
  endwrite_3964  
  endwrite_2160  
  endwrite_2360  
  endwrite_2352  
  endwrite_912  
  endwrite_2376  
  endwrite_4048  
  endwrite_2364  
  endwrite_4076  
  endwrite_4008  
  endwrite_992  
  main_99  
  endwrite_2204  
  endwrite_3884  
  endwrite_2280  
  endwrite_2216  
  endwrite_1632  
  endwrite_740  
  endwrite_3760  
  endwrite_4016  
  endwrite_1220  
  endwrite_1784  
  endwrite_4088  
  endwrite_3964  
  endwrite_2160  
  endwrite_2360  
  endwrite_2352  
  endwrite_912  
  endwrite_2376  
  endwrite_4048  
  endwrite_2364  
  endwrite_4076  
  endwrite_4008  
  endwrite_992  
   
  看来MSDN没什么错,异步和多线程没什么区别,但我还是觉得递归调用异步函数不好,不够清晰。 问题点数:100、回复次数:10Top

1 楼VirtualDesktop(^_^)回复于 2006-09-19 18:27:03 得分 2

回调函数在新线程执行的Top

2 楼IceboundRock()回复于 2006-09-20 19:08:16 得分 20

异步有的时候用普通的线程,有的时候用系统的异步调用功能。  
  有一些IO操作也是异步的,但是未必需要一个线程来运行。例如:硬件是有DMA功能的,在调用DMA传输数据的时候,CPU是不需要执行处理的,只需要发起传输和等待传输结束即可。  
  具体到.net平台,比如Socket的BeginSend,如果是运行在Windows   2000以后的平台,在底层就会调用异步的完成端口来发送。  
  Top

3 楼bnflower()回复于 2006-09-21 09:49:40 得分 5

.Net中的异步执行其实使用的是异步委托。异步委托将要执行的方法提交到.net的线程池,由  
  线程池中的线程来执行异步方法。Top

4 楼xiyou(溪游at福州)回复于 2006-09-21 10:43:44 得分 0

谢谢上面兄弟的回答。  
  我在socket编程的时候,开始以为异步委托的回调函数在主线程运行。  
  后来觉得不对,于是有了上面的测试。  
  现在有些明白:与多线程比那些异步函数在内部有些优化。  
   
  还有些不明白的地方  
  MSDN中 ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpconnon-blockingclientsocketexample.htm  
          private   static   void   ReceiveCallback(   IAsyncResult   ar   )   {  
                          StateObject   state   =   (StateObject)   ar.AsyncState;  
                          Socket   client   =   state.workSocket;  
                          int   bytesRead   =   client.EndReceive(ar);  
                          if   (bytesRead   >   0)   {  
                                  client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,new   AsyncCallback(ReceiveCallback),   state);  
                          }   else   {  
                                  receiveDone.Set();  
                          }  
          }  
  一直在递归调用异步函数,我觉得已经是另一线程了,用while()就可以,为什么要用递归,还频繁线程上进进出出?Top

5 楼IceboundRock()回复于 2006-09-22 23:51:56 得分 5

其实这个方法是想保证Receive数据的顺序。前一个接收完成之后再发起后一个接收。并不是递归。Top

6 楼www_123du_com(鼠·神·泪)回复于 2006-09-23 00:01:09 得分 25

异步执行也得执行,不在当前线程执行,当然得去另外一个线程执行。  
   
  异步通常用系统线程池的线程,通常情况下性能好些。(因为可以多次利用,申请时不需要重新申请一个线程,只需要从池里取就行了。)  
   
  异步是一种效果,多线程是一种具体技术。可以说,用“多线程”实现“异步”。Top

7 楼holerescue(人因理想而伟大)回复于 2006-09-23 23:34:04 得分 25

异步和多线程是两个不同的概念,不能这样比较。  
  异步请求一般用在IO等耗时操作上,他的好处是函数调用立即返回,相应的工作线程立即返还给系统以供重用。由于系统的线程资源是非常宝贵的,通常有一定的数目限制,如.net默认是25。若使用异步方式,用这些固定数目的线程在固定的时间内就可以服务更多的请求,而如果用同步方式,那么每个请求都自始至终占用这一个线程,服务器可以同时服务的请求数就少了。当异步操作执行完成后,系统会从可用线程中选取一个执行回调程序,这时的这个线程可能是刚开始发出请求的那个线程,也可能是其他的线程,因为系统选取线程是随机的事情,所以不能说绝对不是刚开始的那个线程。  
  多线程是用来并发的执行多个任务。想必楼主应该清楚这个概念。Top

8 楼bejon(阿牛[如果我懂,必坦诚相告;如果您懂,请不吝赐教。])回复于 2006-09-23 23:48:36 得分 10

楼主认为,异不只不过是优化的多线程,我挺认同的。  
  不过有个问题,异步有时优先级比主线程还高。这个特点和多线程不同。Top

9 楼libraworm(我要改名)回复于 2006-09-24 17:13:39 得分 8

异步跟多线程不算是一个概念吧。  
  异步是一中表现形式,多线程是一中实现手段。  
   
  另外,回调是否用多线程完全取决于你的调用方式,很简单的例子,Array的排序就是回调的IComparer的接口,但很明显排序不是多线程的。Top

10 楼xiyou(溪游at福州)回复于 2006-09-27 08:54:22 得分 0

多谢上面兄弟们的回答,虽然还是有些迷糊,不过已经足够我判断项目什么地方需要用异步。  
   
  这几天比较忙,没上。最后问一个问题,大家的这方面知识是从什么地方得到的,是从书上,MSDN上,国内网络,国外网络?我看过的书上没有说这方面的知识,MSDN,国内网络上也没有搜索到。  
   
  明天结贴。Top

相关问题

关键词

得分解答快速导航

  • 帖主:xiyou
  • VirtualDesktop
  • IceboundRock
  • bnflower
  • IceboundRock
  • www_123du_com
  • holerescue
  • bejon
  • libraworm

相关链接

  • CSDN .NET频道
  • .NET类图书
  • C#类图书
  • .NET类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo