精华内容
下载资源
问答
  • 为什么要封装全局同步异常处理和异步异常处理呢? 原因简单:在整个项目中,很多地方都要用到异常处理,总不能随处都是try-catch吧 在JavaScript中处理异常无外乎两种方式【try-catch】和【Promise-catch】但是两...

    为什么要封装全局同步异常处理和异步异常处理呢?

    原因简单:在整个项目中,很多地方都要用到异常处理,总不能随处都是try-catch吧

     

    在JavaScript中处理异常无外乎两种方式【try-catch】和【Promise-catch】但是两种应用场合完全不一样!

    try-catch----只能处理同步异常【同步和异步不是一个线程,所以同步无法捕捉异步的异常】

    Promise-catch----专门为异步提供的异常处理

     

    封装同步异常处理方法:

    封装一个全局通用的同步try-catch方法【同步和异步不是一个线程,所以同步无法捕捉异步的异常】
        static tryCatchGlobal (asyncFunc) {
            try {
                return asyncFunc();
            } catch (e) {
                console.log(`同步异常捕捉_error:${e}`);
            }
        }

    封装异步异常处理方法: 

    封装一个全局通用的异步Promise的try-catch方法捕捉区块链异步异常错误
        static tryCatchGlobalPromise (asyncFunc, errMsg = "区块链异步异常捕捉") {
            return new Promise((resolve, reject) => {
                // asyncFunc只能是异步方法,且必须返回一个Promise,否则会报错【Promise才有then方法】
                return asyncFunc().then((res) => {
                    resolve(res);
                }).catch((error) => {
                    console.log(`${errMsg}_error:${error}:`);
                    resolve(null);
                });
            });
        }

     

    展开全文
  • WCF在同步和异常调用情况下的异常捕获1 前言 关于WCF的基本信息,我就不在这里介绍了。一来是因为园子中的很多人都介绍过了,而且很是详细,再不行,还可以看书。二来是因为自己的概念表达还不是很好,别误导了大家...
    WCF在同步和异常调用情况下的异常捕获 1 前言
    关于WCF的基本信息,我就不在这里介绍了。一来是因为园子中的很多人都介绍过了,而且很是详细,再不行,还可以看书。二来是因为自己的概念表达还不是很好,别误导了大家。
    在这里,我就直接讲解一种用法,然后贴点代码吧。
    在WCF有一种契约,叫做错误契约FaultContract。
    今天我就讲解一下,在同步和异步调用WCF服务的时候,客户端如何捕获服务端抛出来的异常。捕获之后,如何处理,那就是根据项目的要求了。是提示呢?还是记录日志呢?还是其他什么的。。。。。。。。。。。。
    2 正文
    其他对于同步和异步来说,WCF处理异常的手段是一致的。都是将异常信息,通过我们自定义的一个异常信息类,传输到客户端。客户端获取到这个类的信息,然后就知道了具体的异常。然后如何处理,就是客户端的事情了。
    2.1 服务定义
    错误契约定义
    
    
    1. [DataContract]  
    2.     public class CallException  
    3.     {  
    4.         public CallException() { }  
    5.         public CallException(string message, string detail)  
    6.         { Message = message;  
    7.         Detail = detail;  
    8.         }  
    9.         [DataMember]  
    10.         public string Message { getset; }  
    11.         [DataMember]  
    12.         public string Detail { getset; }  
    13.     } 

     
    接口定义
    
    
    1. [ServiceContract]  
    2.     public interface IService1  
    3.     {  
    4.         [OperationContract]  
    5.         [FaultContract(typeof(CallException))]  
    6.         User GetUserByID(int id,string communCode, out CallException callException);  
    7.  
    8.         [OperationContract]  
    9.         [FaultContract(typeof(CallException))]  
    10.         [ServiceKnownType(typeof(User ))]  
    11.         BaseClass.EntityBase  GetByIDWithAuthentication(int id, out CallException callException);  
    12.     } 
     
     
    接口实现
     
     
    
    
    1. [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]  
    2.    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]  
    3.    [Common.MyServiceBehavior()]  
    4.    public class Service1Impl : BaseClass.ServiceBase, IService1  
    5.    {  
    6.         
    7.        #region IService1 Members  
    8.  
    9.        public User GetUserByID(int id, string communCode, out CallException callException)  
    10.        {  
    11.            callException = null;  
    12.            User user = null;  
    13.            BLL.UserBLL userBll = Common.ServiceLocator.LoadService<BLL.UserBLL>();  
    14.            user= userBll.GetUserByID(id, out callException);  
    15.            return user;  
    16.        }  
    17.  
    18.        //[Common.AuthenticationBehavior()]  
    19.        public BaseClass.EntityBase GetByIDWithAuthentication(int id, out CallException callException)  
    20.        {  
    21.            callException = null;  
    22.            User user = null;  
    23.            BLL.UserBLL userBll = Common.ServiceLocator.LoadService<BLL.UserBLL>();  
    24.            user = userBll.GetByID(id, out callException);  
    25.            return user;  
    26.        }  
    27.  
    28.        #endregion  
    29.    } 
    业务逻辑类
    
    
    1. public class UserBLL : BaseClass.BLLBase  
    2.    {  
    3.        public UserBLL(Common.DALHelper dalHelper)  
    4.        {  
    5.            _dalHelper = dalHelper;  
    6.        }  
    7.        private Common.DALHelper _dalHelper;  
    8.  
    9.  
    10.        [Common.ExceptionCallHandler("你没有权限""""""你没有权限啊BLL")]  
    11.        public User GetByID(int id, out CallException callException)  
    12.        {  
    13.            callException = null;  
    14.            if (id < 10)  
    15.            {  
    16.                callException = new CallException()  
    17.                {  
    18.                    Message = "获取用户",  
    19.                    Detail = "必须大于等于10" 
    20.                };  
    21.                throw new FaultException<CallException>(callException, "parameter error");  
    22.            }  
    23.            else 
    24.            {  
    25.                User user = null;  
    26.                int b = 0;  
    27.                user = _dalHelper.UserDal.GetByID(id, ref b, out callException);  
    28.                return user;  
    29.            }  
    30.        }  
    31.        [Common.ExceptionCallHandler("你没有权限""""""你没有权限啊BLL")]  
    32.        public User GetUserByID(int id, out CallException callException)  
    33.        {  
    34.            User user = null;  
    35.            callException = null;  
    36.            if (id < 10)  
    37.            {  
    38.                callException = new CallException()  
    39.                {  
    40.                    Message = "获取用户",  
    41.                    Detail = "必须大于等于10" 
    42.                };  
    43.            }  
    44.            else 
    45.            {  
    46.                int b = 0;  
    47.                user = _dalHelper.UserDal.GetByID(id, ref b, out callException);  
    48.            } return user;  
    49.        }  
    50.    } 
     
     
    在业务逻辑类中判断参数的合法性,不合法抛出异常。大家看到有两个方法,一个是直接抛出异常,一个是没有抛出任何异常。后面将这两个的用处。
    2.2 同步调用
    同步调用,我们用控制台程序来模拟客户端。
    同步方式调用WCF的时候,我们可以直接try。。。catch。。。来捕获这个异常信息,然后进行处理。
    代码如下:
    
    
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.ServiceModel;  
    6. using System.ServiceModel.Channels;  
    7.  
    8. namespace ConsoleConsumer  
    9. {  
    10.     class Program  
    11.     {  
    12.         static void Main(string[] args)  
    13.         {  
    14.             Service1.Service1Client client = new Service1.Service1Client();  
    15.             using (OperationContextScope scope = new OperationContextScope((IContextChannel)client.InnerChannel))  
    16.             {  
    17.                 MessageHeaders messageHeadersElement = OperationContext.Current.OutgoingMessageHeaders;  
    18.                 messageHeadersElement.Add(MessageHeader.CreateHeader("username""""kd"));  
    19.                 messageHeadersElement.Add(MessageHeader.CreateHeader("password""""kd"));  
    20.             }  
    21.             Console.WriteLine("请输入ID:");  
    22.            int id =int.Parse ( Console.ReadLine());  
    23.             Service1.CallException callException = null;  
    24.             try 
    25.             {  
    26.                   
    27.                 client.GetByIDWithAuthentication(out callException, id);  
    28.                 Console.WriteLine("成功调用");  
    29.             }  
    30.             catch (FaultException<Service1.CallException> ex)  
    31.             {  
    32.                 Console.WriteLine("半路接获CallException Error:{0},{1}", ex.Detail.Message, ex.Detail.Detail);  
    33.             }  
    34.             catch (FaultException<System.IO.EndOfStreamException> ex)  
    35.             {  
    36.                 Console.WriteLine("半路接获EndOfStreamException Error:{0},{1}", ex.Detail.Message, ex.Detail.HelpLink );  
    37.             }  
    38.             catch (Exception ex)  
    39.             {  
    40.                 Console.WriteLine("最后一关 Error:{0},{1}", ex.Message, ex.HelpLink);  
    41.             }  
    42.  
    43.             Console.Read();  
    44.         }  
    45.     }  
    46. }  
     
    主要是看catch (FaultException<Service1.CallException> ex) 这一句。就好像是,WCF将我们的异常信息类包装到FaultException这个类中。然后ex.Detail就是CallException这个我们自定义的实体类型了。那就可以根据这个实体的属性进行异常的处理了。
    2.3 异步调用
    异步调用,我们用Silverlight来模型客户端程序。
    我们都知道,异步调用,其实就是多线程。然后再callback中处理返回的数据。
    这时候,就会发现不能try。。。catch。。。了。因为调用成功,还是失败,是在方法完成的委托函数中才知道的。没有地方给你写try。。。catch。。。了。
    Service1.Service1Client client = new Service1.Service1Client(); client.GetUserByIDCompleted += new EventHandler<Service1.GetUserByIDCompletedEventArgs>(client_GetUserByIDCompleted); client.GetUserByIDAsync(int.Parse(textBox1.Text.Trim()), "123456");

     
    void client_GetUserByIDCompleted(object sender, Service1.GetUserByIDCompletedEventArgs e) { }

     
    是通过e来获取数据的。
    但是异常信息需要通过通道传递的客户端,这点和同步调用是一样的。既然这样,那我们在定义服务端方法的时候,就添加一个out类型的参数,在服务端就将CallException这个实体赋值给这个参数。然后通过e.CallException就可以获取异常信息了,如果不为空,说明有异常存在。为空,说明没有异常,访问正常。
    
    
    1. void client_GetUserByIDCompleted(object sender, Service1.GetUserByIDCompletedEventArgs e)  
    2.       {  
    3.  
    4.           #region  
    5.  
    6.           if (e.callException != null)  
    7.           {  
    8.               ChildWindow win = new ChildWindow();  
    9.               win.Title = e.callException.Message;  
    10.               win.Content = e.callException.Detail;  
    11.               win.MinHeight = 50;  
    12.               win.MinWidth = 200;  
    13.               win.Show();  
    14.           }  
    15.           else 
    16.           {  
    17.               ChildWindow win = new ChildWindow();  
    18.               win.Title = "ok";  
    19.               win.Content = "it is ok";  
    20.               win.MinHeight = 50;  
    21.               win.MinWidth = 200;  
    22.               win.Show();  
    23.           }  
    24.           #endregion  
    25.  
    26.       } 

    3 结论
    不知道大家在捕获和处理WCF的异常的时候,是如何处理的?有更好的办法,欢迎大家一起讨论。
    源码下载:



    本文转自 virusswb 51CTO博客,原文链接:http://blog.51cto.com/virusswb/410798,如需转载请自行联系原作者
    展开全文
  • 同步和异步

    2020-10-01 22:20:01
    同步I/O意味着在I/O操作完成之前,方法被阻塞,I/O操作完成后,方法返回其数据。使用异步I/O,用户可以调用BeginRead。主线程可以继续进行其他工作,稍后,用户将能够处理数据。另外,多个I/O请求可以被同时挂起。 ...

    MFC对SOCKET编程的支持其实是很充分的,然而其文档是语焉不详的。以至于大多数用VC编写的功能稍
    复杂的网络程序,还是使用API的。故CAsyncSocket及CSocket事实上成为疑难,群众多敬而远之。余
    好事者也,不忍资源浪费,特为之注解。

    一、CAsyncSocket与CSocket的区别

    前者是异步通信,后者是同步通信;前者是非阻塞模式,后者是阻塞模式。另外,异步非阻塞模式有
    时也被称为长连接,同步阻塞模式则被称为短连接。为了更明白地讲清楚两者的区别,举个例子:

    设想你是一位体育老师,需要测验100位同学的400米成绩。你当然不会让100位同学一起起跑,因为当
    同学们返回终点时,你根本来不及掐表记录各位同学的成绩。

    如果你每次让一位同学起跑并等待他回到终点你记下成绩后再让下一位起跑,直到所有同学都跑完。恭
    喜你,你已经掌握了同步阻塞模式。

    你设计了一个函数,传入参数是学生号和起跑时间,返回值是到达终点的时间。你调用该函数100次,
    就能完成这次测验任务。这个函数是同步的,因为只要你调用它,就能得到结果;这个函数也是阻塞的,
    因为你一旦调用它,就必须等待,直到它给你结果,不能去干其他事情。

    如果你一边每隔10秒让一位同学起跑,直到所有同学出发完毕;另一边每有一个同学回到终点就记录成
    绩,直到所有同学都跑完。恭喜你,你已经掌握了异步非阻塞模式。

    你设计了两个函数,其中一个函数记录起跑时间和学生号,该函数你会主动调用100次;另一个函数记
    录到达时间和学生号,该函数是一个事件驱动的callback函数,当有同学到达终点时,你会被动调用。
    你主动调用的函数是异步的,因为你调用它,它并不会告诉你结果;这个函数也是非阻塞的,因为你一
    旦调用它,它就马上返回,你不用等待就可以再次调用它。但仅仅将这个函数调用100次,你并没有完
    成你的测验任务,你还需要被动等待调用另一个函数100次。

    当然,你马上就会意识到,同步阻塞模式的效率明显低于异步非阻塞模式。那么,谁还会使用同步阻塞
    模式呢?

    不错,异步模式效率高,但更麻烦,你一边要记录起跑同学的数据,一边要记录到达同学的数据,而且
    同学们回到终点的次序与起跑的次序并不相同,所以你还要不停地在你的成绩册上查找学生号。忙乱之
    中你往往会张冠李戴。

    你可能会想出更聪明的办法:你带了很多块秒表,让同学们分组互相测验。恭喜你!你已经掌握了多线
    程同步模式!

    每个拿秒表的同学都可以独立调用你的同步函数,这样既不容易出错,效率也大大提高,只要秒表足够
    多,同步的效率也能达到甚至超过异步。

    可以理解,你现的问题可能是:既然多线程同步既快又好,异步模式还有存在的必要吗?

    很遗憾,异步模式依然非常重要,因为在很多情况下,你拿不出很多秒表。你需要通信的对端系统可能
    只允许你建立一个SOCKET连接,很多金融、电信行业的大型业务系统都如此要求。

    现在,你应该已经明白了:CAsyncSocket用于在少量连接时,处理大批量无步骤依赖性的业务。CSocket
    用于处理步骤依赖性业务,或在可多连接时配合多线程使用。


    二、CAsyncSocket异步机制

    当你获得了一个异步连接后,实际上你扫除了发送动作与接收动作之间的依赖性。所以你随时可以发包,
    也随时可能收到包。发送、接收函数都是异步非阻塞的,顷刻就能返回,所以收发交错进行着,你可以
    一直工作,保持很高的效率。但是,正因为发送、接收函数都是异步非阻塞的,所以仅调用它们并不能
    保障发送或接收的完成。例如发送函数Send,调用它可能有4种结果:

    1、错误,Send()==SOCKET_ERROR,GetLastError()!=WSAEWOULDBLOCK,这种情况可能由各种网络问题导
    致,你需要马上决定是放弃本次操作,还是启用某种对策

    2、忙,Send()==SOCKET_ERROR,GetLastError()==WSAEWOULDBLOCK,导致这种情况的原因是,你的发送
    缓冲区已被填满或对方的接受缓冲区已被填满。这种情况你实际上不用马上理睬。因为CAsyncSocket会
    记得你的Send WSAEWOULDBLOCK了,待发送的数据会写入CAsyncSocket内部的发送缓冲区,并会在不忙的
    时候自动调用OnSend,发送内部缓冲区里的数据。

    3、部分完成,0<Send(pBuf,nLen)<nLen,导致这种情况的原因是,你的发送缓冲区或对方的接收缓冲区
    中剩余的空位不足以容纳你这次需要发送的全部数据。处理这种情况的通常做法是继续发送尚未发送的
    数据直到全部完成或WSAEWOULDBLOCK。这种情况很容易让人产生疑惑,既然缓冲区空位不足,那么本次
    发送就已经填满了缓冲区,干嘛还要继续发送呢,就像WSAEWOULDBLOCK了一样直接交给OnSend去处理剩
    余数据的发送不是更合理吗?然而很遗憾,CAsyncSocket不会记得你只完成了部分发送任务从而在合适
    的时候触发OnSend,因为你并没有WSAEWOULDBLOCK。你可能认为既然已经填满缓冲区,继续发送必然会
    WSAEWOULDBLOCK,其实不然,假如WSAEWOULDBLOCK是由于对方读取接收缓冲区不及时引起的,继续发送
    的确很可能会WSAEWOULDBLOCK,但假如WSAEWOULDBLOCK是由于发送缓冲区被填满,就不一定了,因为你
    的网卡处理发送缓冲区中数据的速度不见得比你往发送缓冲区拷贝数据的速度更慢,这要取决与你竞争
    CPU、内存、带宽资源的其他应用程序的具体情况。假如这时候CPU负载较大而网卡负载较低,则虽然刚
    刚发送缓冲区是满的,你继续发送也不会WSAEWOULDBLOCK。

    4、完成,Send(pBuf,nLen)==nLen

    与OnSend协助Send完成工作一样,OnRecieve、OnConnect、OnAccept也会分别协助Recieve、Connect、
    Accept完成工作。这一切都通过消息机制完成:

    在你使用CAsyncSocket之前,必须调用AfxSocketInit初始化WinSock环境,而AfxSocketInit会创建一个
    隐藏的CSocketWnd对象,由于这个对象由Cwnd派生,因此它能够接收Windows消息。所以它能够成为高层
    CAsyncSocket对象与WinSock底层之间的桥梁。例如某CAsyncSocket在Send时WSAEWOULDBLOCK了,它就会
    发送一条消息给CSocketWnd作为报告,CSocketWnd会维护一个报告登记表,当它收到底层WinSock发出的
    空闲消息时,就会检索报告登记表,然后直接调用报告者的OnSend函数。所以前文所说的CAsyncSocket会
    自动调用OnXxx,实际上是不对的,真正的调用者是CSocketWnd——它是一个CWnd对象,运行在独立的线
    程中。

    使用CAsyncSocket时,Send流程和Recieve流程是不同的,不理解这一点就不可能顺利使用CAsyncSocket。

    MSDN对CAsyncSocket的解释很容易让你理解为:只有OnSend被触发时你Send才有意义,你才应该Send,
    同样只有OnRecieve被触发时你才应该Recieve。很不幸,你错了:

    你会发现,连接建立的同时,OnSend就第一次被触发了,嗯,这很好,但你现在还不想Send,你让OnSend
    返回,干点其他的事情,等待下一次OnSend试试看?实际上,你再也等不到OnSend被触发了。因为,除
    了第一次以外,OnSend的任何一次触发,都源于你调用了Send,但碰到了WSAEWOULDBLOCK!

    所以,使用CAsyncSocket时,针对发送的流程逻辑应该是:你需两个成员变量,一个发送任务表,一个
    记录发送进度。你可以,也应该,在任何你需要的时候,主动调用Send来发送数据,同时更新任务表和
    发送进度。而OnSend,则是你的负责擦屁股工作的助手,它被触发时要干的事情就是根据任务表和发送
    进度调用Send继续发。若又没能将任务表全部发送完成,更新发送进度,退出,等待下一次OnSend;若
    任务表已全部发送完毕,则清空任务表及发送进度。

    使用CAsyncSocket的接收流程逻辑是不同的:你永远不需要主动调用Recieve,你只应该在OnRecieve中等
    待。由于你不可能知道将要抵达的数据类型及次序,所以你需要定义一个已收数据表作为成员变量来存储
    已收到但尚未处理的数据。每次OnRecieve被触发,你只需要被动调用一次Recieve来接受固定长度的数据,
    并添加到你的已收数据表后。然后你需要扫描已收数据表,若其中已包含一条或数条完整的可解析的业务
    数据包,截取出来,调用业务处理窗口的处理函数来处理或作为消息参数发送给业务处理窗口。而已收数
    据表中剩下的数据,将等待下次OnRecieve中被再次组合、扫描并处理。

    在长连接应用中,连接可能因为各种原因中断,所以你需要自动重连。你需要根据CAsyncSocket的成员变
    量m_hSocket来判断当前连接状态:if(m_hSocket==INVALID_SOCKET)。当然,很奇怪的是,即使连接已经
    中断,OnClose也已经被触发,你还是需要在OnClose中主动调用Close,否则m_hSocket并不会被自动赋值
    为INVALID_SOCKET。

    在很多长连接应用中,除建立连接以外,还需要先Login,然后才能进行业务处理,连接并Login是一个步
    骤依赖性过程,用异步方式处理反而会很麻烦,而CAsyncSocket是支持切换为同步模式的,你应该掌握在
    适当的时候切换同异步模式的方法:

    DWORD dw;

    //切换为同步模式
    dw=0;
    IOCtl(FIONBIO,&dw);
    ...

    //切换回异步模式
    dw=1;
    IOCtl(FIONBIO,&dw);


    三、CSocket的用法

    CSocket在CAsyncSocket的基础上,修改了Send、Recieve等成员函数,帮你内置了一个用以轮询收发缓冲区
    的循环,变成了同步短连接模式。

    短连接应用简单明了,CSocket经常不用派生就可以直接使用,但也有些问题:

    1、用作监听的时候

    曾经看到有人自己创建线程,在线程中创建CSocket对象进行Listen、Accept,若Accept成功则再起一个线
    程继续Listen、Accept。。。可以说他完全不理解CSocket,实际上CSocket的监听机制已经内置了多线程机
    制,你只需要从CSocket派生,然后重载OnAccept:

    //CListenSocket头文件
    class CListenSocket : public CSocket
    {
    public:
        CListenSocket(HWND hWnd=NULL);
        HWND m_hWnd; //事件处理窗口
        virtual void OnAccept(int nErrorCode);
    };

    //CListenSocket实现文件
    #include "ListenSocket.h"
    CListenSocket::CListenSocket(HWND hWnd){m_hWnd=hWnd;}
    void CListenSocket::OnAccept(int nErrorCode)
    {
        SendMessage(m_hWnd,WM_SOCKET_MSG,SOCKET_CLNT_ACCEPT,0);
        CSocket::OnAccept(nErrorCode);
    }

    //主线程
    ...
    m_pListenSocket=new CListenSocket(m_hWnd);
    m_pListenSocket->Create(...);
    m_pListenSocket->Listen();
    ...

    LRESULT CXxxDlg::OnSocketMsg(WPARAM wParam, LPARAM lParam)
    {
        UINT type=(UINT)wParam;
        switch(type)
        {
        case SOCKET_CLNT_ACCEPT:
            {
                CSocket* pSocket=new CSocket;
                if(!m_pListenSocket->Accept(*pSocket))
                {
                    delete pSocket;
                    break;
                }
                ...
            }
        ...
        }
    }


    2、用于多线程的时候

    常看到人说CSocket在子线程中不能用,其实不然。实际情况是:

    直接使用CSocket动态创建的对象,将其指针作为参数传递给子线程,则子线程中进行收发等各种操作都
    没问题。但如果是使用CSocket派生类创建的对象,就要看你重载了哪些方法,假如你仅重载了OnClose,
    则子线程中你也可以正常收发,但不能Close!

    因为CSocket是用内部循环做到同步的,并不依赖各OnXxx,它不需要与CSocketWnd交互。但当你派生并重
    载OnXxx后,它为了提供消息机制就必须与CSocketWnd交互。当你调用AfxSocketInit时,你的主线程会获
    得一个访问CSocketWnd的句柄,对CSocketWnd的访问是MFC自动帮你完成的,是被隐藏的。而你自己创建
    的子线程并不自动具备访问CSocketWnd的机制,所以子线程中需要访问CSocketWnd的操作都会失败。

    常看到的解决办法是给子线程传递SOCKET句柄而不是CSocket对象指针,然后在子线程中创建CSocket临时
    对象并Attach传入的句柄,用完后再Dettach并delete临时对象。俺没有这么干过,估计是因为Attach方法
    含有获取CSocketWnd句柄的内置功能。

    俺的解决方案还是使用自定义消息,比如俺不能在子线程中Close,那么,俺可以给主线程发送一条消息,
    让主线程的消息处理函数来完成Close,也很方便。

    CSocket一般配合多线程使用,只要你想收发数据,你就可以创建一个CSocket对象,并创建一个子线程来
    进行收发。所以被阻塞的只是子线程,而主线程总是可以随时创建子线程去帮它干活。由于可能同时有很
    多个CSocket对象在工作,所以你一般还要创建一个列表来储存这些CSocket对象的标识,这样你可能通过
    在列表中检索标识来区分各个CSocket对象,当然,由于内存地址的唯一性,对象指针本身就可以作为标识。


    相对CAsyncSocket而言,CSocket的运作流程更直观也更简单

    展开全文
  • 同步和异步的区别

    2020-09-08 10:46:44
    目录同步概念优点使用场景异步概念优点使用场景两者比较 同步 概念 我们可以将同步看成是单线的执行,即要么执行成功,要么执行失败,反正就是要返回一个结果,在没有得到这个结果之前什么都不干,就傻傻的等着。 ...

    同步

    概念

    我们可以将同步看成是单线的执行,即要么执行成功,要么执行失败,反正就是要返回一个结果,在没有得到这个结果之前什么都不干,就傻傻的等着。

    任务提交后不向系统交出控制权,持续等待。

    优点

    1、同步流程对结果处理通常更为简单,可以就近处理。

    2、同步流程对结果的处理始终和前文保持在一个上下文内。

    3、同步流程可以很容易捕获、处理异常。

    4、同步流程是最天然的控制过程顺序执行的方式。

    使用场景

    比如银行的转账系统,对数据库的保存操作等等,都会使用同步交互操作,其余情况都优先使用异步交互。

    异步

    概念

    异步则是当你的任务提交了之后,不用管任务的结果是什么,可以继续执行别的任务。

    任务提交后将控制权交予系统,系统可以进行其他任务的执行。

    优点

    1、异步流程可以立即给调用方返回初步的结果。

    2、异步流程可以延迟给调用方最终的结果数据,在此期间可以做更多额外的工作,例如结果记录等等。

    3、异步流程在执行的过程中,可以释放占用的线程等资源,避免阻塞,等到结果产生再重新获取线程处理。

    4、异步流程可以等多次调用的结果出来后,再统一返回一次结果集合,提高响应效率

    使用场景

    1、不涉及共享资源,或对共享资源只读,即非互斥操作

    2、没有时序上的严格关系

    3、不需要原子操作,或可以通过其他方式控制原子性

    4、常用于IO操作等耗时操作,因为比较影响客户体验和使用性能

    5、不影响主线程逻辑

    两者比较

    1、同步的执行效率会比较低,耗费时间,但有利于我们对流程进行控制,避免很多不可掌控的意外情况;
    2、异步的执行效率高,节省时间,但是会占用更多的资源,也不利于我们对进程进行控制

    展开全文
  • 线程同步和异步锁的几种方式

    万次阅读 2018-09-10 11:12:09
    同步锁:当在一个java虚拟机多个线程...先看下一个线程异常的售票 public class ThreadSafe { public static void main(String[] args) { MyThread t1 = new MyThread("窗口一"); MyThread t2 ...
  • 异常处理方法,同步VS异步

    千次阅读 2013-03-29 16:19:59
    VC默认情况下是同步异常捕捉,所以只有throw才算是正式异常,而 对内存访问出错除零则不保证正能正确解栈(可能导致栈上的对象 未被析构) 1. Windows SEH 与 C++ Exception  1)
  • 同步和异步的好处

    2012-01-06 21:28:50
    同步处理和异步处理的好处比较:   同步的好处: 1、同步流程对结果处理通常更为简单,可以就近处理。 2、同步流程对结果的处理始终和前文保持在一个上下文内。 3、同步流程可以很容易捕获、处理异常。 4、...
  • 自动位移提交的方式在正常情况下不会发生消息丢失或重复消费的现象,但是在编程的世界里异常无可避免,与此同时,自动位移提交也无法做到精确的位移管理。 在Kafka 中还提供了手动位移提交的方式,这样可以使得开发...
  • 分布式 - RPC同步和异步说明

    千次阅读 2018-09-13 17:20:12
    要实时就用同步,要吞吐率就用异步同步调用 流程略 实现负载均衡:连接池中建立了与一个RPC-server集群的连接,连接池在返回连接的时候,需要具备负载均衡策略。 实现故障转移:连接池中建立了与一个RPC-...
  • 同步时序电路和异步时序电路

    千次阅读 2019-06-18 10:06:10
    缺点,触发器状态刷新不同步,信号延迟可能会累积从而出现状态异常。 简而言之: 同步电路:存储电路中所有触发器的时钟输入端都接同一个时钟脉冲源,因而所有触发器的状态的变化都与所加的时钟脉冲信...
  • 同步和异步 所有的方法都有异步和同步的形式; 异步方法的最后一个参数都是一个回调函数。传给回调函数的参数取决于具体方法,但回调函数的第一个参数都会保留给异常,如果操作成功完成,则第一个参数会是null和...
  • 对于“中断是异步的,异常同步的“的理解 首先弄懂一个概念,那就是如果CPU检测到多个中断请求的话,会选择中断优先级高的中断来处理。将中断处理完之后,接下来再执行调度程序。 中断的引入,是为了支持CPU...
  • ajax优点: 1.页面无刷新,实现按需加载,用户体验非常好 2.不打断用户的操作,实现异步请求,具备更加迅速的响应能力 3.可以将服务端的一些行为...同步和异步区别: 同步:js本身是一个阻塞的语言,需要逐行读...
  • 异常分为同步异常和异步异常。 中断属于异步异常。 RTT建议在中断中采用信号量、消息、事件来标记。 中断相关的硬件:外设、中断控制器、CPU。 中断过程:外设产生中断,中断控制器设置优先级等并向CPU发送中断信号...
  • 首先,来粗略地看看同步和异步各自有些什么好处: 同步的好处:1、同步流程对结果处理通常更为简单,可以就近处理。2、同步流程对结果的处理始终和前文保持在一个上下文内。3、同步流程可以很容易捕获、处理异常。4...
  • 在ARM64体系结构中,异常分为同步异常和异步异常。 同步异常: (1)系统调用 (2)数据中止 (3)指令中止 (4)栈指针或指令地址没有对齐 (5)没有定义的指令 (6)调试异常 异步异常: (1)中断(IRQ) ..
  • 文章目录1.0 中断(interruupt)2.0 异常(exception)3.0 同步异常和异步异常3.1 同步异常(synchronous exception)3.2 异步异常(asynchronous exception)3.2.0 精确异步异常(precise)3.2.1 非精确异步异常...
  • WCF在同步和异常调用情况下的异常捕获 同步调用使用Console模拟客户端 异步调用使用Silverlight模拟客户端
  • 广义上来说中断和异常都被处理器视为异常,一般将其分为同步异常和异步异常 同步异常 同步异常:由于执行程序指令流或者试图执行程序指令流而造成的异常 表现:CPU外部环境一定,多次执行时每次能够精确复现 常见的...
  • 同步编程中的异常处理由trycatch,同样异步编程时,异步调用的方法抛出一个异常时,CLR会捕捉他,当调用者线程(启动异步调用的线程)调用EndInvoke时,CLR会再次将异常抛出,这样调用者线程可捕获到她。...
  • ARMv8 64bits相对于之前的 32bits 有较大变动,所有中断及异常的处理总入口都在...分为同步和异步 两种类型异常,中断划入异步异常类型: Synchronous(同步异常) 异常类型 描述 Undefined Instruction
  • C++串口同步和异步的读取与串口设备编程

    万次阅读 多人点赞 2016-09-19 23:06:45
    为了使得程序更加清晰文中的代码去除了异常处理的情况。文中加粗的文字相应的比较重要,需要多注意。当然文中会有错误,欢迎评论指正。文章中代码下载地址 http://pan.baidu.com/s/1pLsP9wB1、COM口WindowsAPI函数...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 982
精华内容 392
关键字:

同步异常和异步异常