职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 942|回复: 0

.NET关于同步、异步及Socket

[复制链接]
joe 发表于 2007-2-8 18:58 | 显示全部楼层 |阅读模式
以SOCKET通信中的异步方法为例:

public static ManualResetEvent ConnectDone = new ManualResetEvent(false);

    public static void ConnectCallback(IAsyncResult ar)

    {

        Socket sClient = (Socket)ar.AsyncState;

        sClient.EndConnect(ar);

        Console.WriteLine(\"Socket connected to {0}\", sClient.RemoteEndPoint.ToString());

        ConnectDone.Set();

}

    public static void Main(string[] arg)

    {

        try

        {

            IPHostEntry ipHost = Dns.Resolve(\"127.0.0.1\");

            IPAddress ipAddr = ipHost.AddressList[0];

            IPEndPoint endPoint = new IPEndPoint(ipAddr, 11000);

            Socket sClient = new Socket(AddressFamily.InterNetwork,

                                        SocketType.Stream, ProtocolType.Tcp);

        Client.BeginConnect(endPoint, new AsyncCallback(ConnectCallback),sClient);

                        for (int i = 0; i <5; i++)

                Console.WriteLine(\"Do Some Other Work.\");

                     byte[] byteData = Encoding.ASCII.GetBytes(\"Some Data.\");

           ConnectDone.WaitOne();

            

            sClient.BeginSend(byteData, 0, byteData.Length, 0,

                              new AsyncCallback(SendCallback), sClient);

            

            ………

    }

(注:ManualResetEvent 允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。

ManualResetEvent就像一个信号灯,可以利用它的信号来通知其它线程。它有几个重要的方法:Reset(),Set(),WaitOne()。初始化该对象时,用户可以指定其默认的状态(有信号/无信号),在初始化以后,该对象将保持原来的状态不变直到它的Reset()或者Set()方法被调用,Reset()方法将其设置为无信号状态,Set()方法将其设置为有信号状态。WaitOne()方法使当前线程挂起直到ManualResetEvent对象处于有信号状态,此时该线程将被激活。)

本例中,主线程调用ConnectDone.WaitOne();后,主线程阻塞,直到连接操作(即ConnectCallback)完成,因为连接操作完成之后,执行了ConnectDone.Set()将信号灯设置为有信号,由于调用了ManualResetEvent.WaitOne()方法而处在等待状态的主线程将接收到这个信号,于是它接着往下执行,完成后边的工作。

同步与异步:

简单地说,同步即程序执行一个方法,等该方法返回之后,继续往下走,

异步:即程序调用一个方法后立即返回,“宏观”而言,主线程与方法线程并行执行。

就本例而言,socket的异步方法BeginConnect被调用后,接着执行主线程中该语句之后的代码,即:

for (int i = 0; i <5; i++)

Console.WriteLine(\"Do Some Other Work.\");

byte[] byteData = Encoding.ASCII.GetBytes(\"Some Data.\");

如果调用的是同步方法,那么,输出“Socket connected to…”一定会在“Do Some Other Work.”之前,因为主线程必须等待同步方法的返回,但是在异步的情况下,将可能在5行“Do Some Other Work.”之间的某个时刻出现“Socket connected to…”的输出(实际情况还依赖于操作系统的线程调度)。

至于在sClient.BeginSend(…)方法之前调用ConnectDone.WaitOne(),则是由于前者依赖于连接操作(即ConnectCallback)的完成,须得同步一下。
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-5-11 22:08 , Processed in 0.152522 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表