首页 -> 资讯 > 要闻 > 正文

世界要闻:我在使用Winform7.0开发海康相机应用的时候系统悄无声息的退出

    来源: 博客园  2023-06-29 17:29:25


【资料图】

一、简介1、说明一下最近,我在开发一个玻璃幕墙检测的项目,这个项目需要使用到海康的相机系统。业务是这样的,相机按着指定的坐标,扫描玻璃幕墙的每块玻璃,通过算法查看是否有损坏的,如果有就发出报警信息,告诉客户。这个项目是有一个同事写好的,我后来重构了一下,但是运行起来,运行若干次,就退悄无声息的退出软件,什么也不提示。通过这个现象,我知道肯定是和硬件交互的时候出了问题,而且抛出任何异常。海康的日志文件也没有显示是什么有价值的东西。        但是,通过努力的查找,调试,排除,终于找到了问题的关键,我们有四个相机,就有四个回调函数,用于处理图像,但是每个相机注册了一个自己的回调,应该是四个相机,设置四个回调,但是回调函数的实例是一个,否则就会出现程序毫无征兆的崩溃。    2、开发平台开发工具:Visual Studio2022        开发语言:C#        开发平台:Winform 7.0        海康类库:MvCamCtrl.NET二、详细步骤这个问题搞了我两天才搞定,但是搞定了,心里舒服了。今天就把思路写下来,自己可以查找,也可以帮助大家。    知道问题的关键点了,解决也就方便了。这也叫难着不会,会的不难。

1、一定要把 MyCamera.cbOutputExdelegate 声明为类的成员。private MyCamera.cbOutputExdelegate _outputImageDelegate;

1      #region 私有实例字段 2  3         private MyCamera[]? _myCameras;//相机实例的数组。 4         private MyCamera.MV_CC_DEVICE_INFO_LIST _deviceInformationList;//相机信息的列表 5         7         //图片文件的存储路径:根目录/当前扫描时间(作为目录)/相机编号 8         private string? _saveImageBaseDirectory;   //图像文件存储的根路径路径。 9         private string? _saveImageOnceTimeDirectory;   //单次扫描图像文件的存储路径,目录结构:根目录+当前扫描时间10         private string[]? _saveImageForCameraDirectory;//最终存储图片文件的路径,目录结构:根目录+当前扫描时间+相机序列号(有多少台相机,就有多少个目录)11         private IntPtr[]? _imageDisplayHandles;//针对每台相机图像进行显示处理,应为有多台,所以是数据类型是数组。14         privateMyCamera.cbOutputExdelegate _outputImageDelegate;17         #endregion

2、一定要在构造函数里初始化,当然,如果你可以保证一个实例,就可以放在其他地方,我是为了方便,没有过多的设计。_outputImageDelegate = new MyCamera.cbOutputExdelegate(SaveImageCallBack);      

1     ///  2         /// 初始化新实例。 3         ///  4         public frmMonitoring() 5         { 6             InitializeComponent(); 7             _outputImageDelegate = new MyCamera.cbOutputExdelegate(SaveImageCallBack);8             _patrolProcessor = new OrientalMotorPatrolProcessor(); 9           10 11             #region 全局异常处理12 13             AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;14             Application.ThreadException += Application_ThreadException;15 16             #endregion17         }

这是附送的方法,异常处理。

1     #region 异常处理 2  3         ///  4         /// 该方法处理用于处理 Windows 窗体线程引发的异常。 5         ///  6         ///  7         ///  8         ///  9         private void Application_ThreadException(object sender, ThreadExceptionEventArgs e)10         {11             try12             {13                 ShowPromptMessage(e.Exception.Message);14             }15             catch (Exception)16             {17                 try18                 {19                     ShowPromptMessage("不可恢复的非 Windows 窗体线程异常,应用程序将退出!");20                 }21                 finally22                 {23                     Application.Exit();24                 }25             }26         }27 28         /// 29         /// 使用该方法处理非UI线程所发生的异常。30         /// 31         /// 32         /// 33         /// 34         private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)35         {36             try37             {38                 var exceptionObject = e.ExceptionObject as Exception;39                 if (exceptionObject != null)40                 {41                     ShowPromptMessage(exceptionObject.Message);42                 }43             }44             catch (Exception)45             {46                 try47                 {48                     ShowPromptMessage("不可恢复的非 Windows 窗体线程异常,应用程序将退出!");49                 }50                 finally51                 {52                     Application.Exit();53                 }54             }55 56         }57 58         #endregion 

辅助方法。    

1      ///  2         /// 用于显示系统的提示信息,包括异常信息、操作信息等。 3         ///  4         /// 需要显示的信息内容。 5         /// 具体操作的状态码值,该值可有可无,不是所有操作都有状态值的,默认值:0,表示没有状态值。 6         private void ShowPromptMessage(string message, int stateCode = 0) 7         { 8             string resultMessage; 9             if (stateCode == 0)10             {11                 resultMessage = $"{message}\r\n";12             }13             else14             {15                 resultMessage = $"{message}: Error ={string.Format("{0:X}", stateCode)}";16             }17 18             switch (stateCode)19             {20                 case MyCamera.MV_E_HANDLE: resultMessage += ",错误或无效句柄(Error or invalid handle)\r\n"; break;21                 case MyCamera.MV_E_SUPPORT: resultMessage += ",不支持的功能(Not supported function)\r\n"; break;22                 case MyCamera.MV_E_BUFOVER: resultMessage += ",缓存已满(Cache is full)\r\n"; break;23                 case MyCamera.MV_E_CALLORDER: resultMessage += ",函数调用顺序错误(Function calling order error)\r\n"; break;24                 case MyCamera.MV_E_PARAMETER: resultMessage += ",不正确的参数(Incorrect parameter)\r\n"; break;25                 case MyCamera.MV_E_RESOURCE: resultMessage += ",应用资源失败(Applying resource failed)\r\n"; break;26                 case MyCamera.MV_E_NODATA: resultMessage += ",没有数据(No data )\r\n"; break;27                 case MyCamera.MV_E_PRECONDITION: resultMessage += ",前提条件错误,或运行环境已更改(Precondition error, or running environment changed)\r\n"; break;28                 case MyCamera.MV_E_VERSION: resultMessage += ",版本不匹配(Version mismatches)\r\n"; break;29                 case MyCamera.MV_E_NOENOUGH_BUF: resultMessage += ",内存不足(Insufficient memory)\r\n"; break;30                 case MyCamera.MV_E_UNKNOW: resultMessage += ",未知错误(Unknown error)\r\n"; break;31                 case MyCamera.MV_E_GC_GENERIC: resultMessage += ",一般错误(General error)\r\n"; break;32                 case MyCamera.MV_E_GC_ACCESS: resultMessage += ",节点访问条件错误(Node accessing condition error)\r\n"; break;33                 case MyCamera.MV_E_ACCESS_DENIED: resultMessage += ",没有权限(No permission)\r\n"; break;34                 case MyCamera.MV_E_BUSY: resultMessage += ",设备正忙或网络断开连接(Device is busy, or network disconnected)\r\n"; break;35                 case MyCamera.MV_E_NETER: resultMessage += ",网络错误(Network error)\r\n"; break;36             }37 38             SetAsyncControlText(txtExceptionMessage, $">> {resultMessage}", true);39         }

3、实例化相机,并初始化回调函数。

1          MyCamera.MV_CC_DEVICE_INFO[] _deviceInfoArray = new MyCamera.MV_CC_DEVICE_INFO[localDeviceCount]; 2                 object? localDeviceInfo = null; 3                 MyCamera.MV_CC_DEVICE_INFO device;                 4  5                 for (int i = 0; i < localDeviceCount; ++i) 6                 { 7                     if (_deviceInformationList.pDeviceInfo != null && _deviceInformationList.pDeviceInfo.Length > 0) 8                     { 9                         localDeviceInfo = Marshal.PtrToStructure(_deviceInformationList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));10                         if (localDeviceInfo != null)11                         {12                             //获取选择的设备信息13                             device = (MyCamera.MV_CC_DEVICE_INFO)localDeviceInfo;14 15                             //打开设备16                             if (cameras[i] == null)17                             {18                                 cameras[i] = new MyCamera();19                             }20 21                             stateCode = cameras[i].MV_CC_CreateDevice_NET(ref device);22                             if (MyCamera.MV_OK != stateCode)23                             {24                                 return;25                             }26 27                             stateCode = cameras[i].MV_CC_OpenDevice_NET();28                             if (MyCamera.MV_OK != stateCode)29                             {30                                 return;31                             }32                             else33                             {34                                 _deviceInfoArray[i] = device;35                                 // 探测网络最佳包大小(只对GigE相机有效),我们是USB相机36                                 if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)37                                 {38                                     int nPacketSize = cameras[i].MV_CC_GetOptimalPacketSize_NET();39                                     if (nPacketSize > 0)40                                     {41                                         stateCode = cameras[i].MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);42                                         if (stateCode != MyCamera.MV_OK)43                                         {44                                             ShowPromptMessage("Warning: Set Packet Size failed {0:x8}", stateCode);45                                         }46                                     }47                                     else48                                     {49                                         ShowPromptMessage("Warning: Get Packet Size failed {0:x8}", stateCode);50                                     }51                                 }52 53                                 //1、开启设置触发模式                                54                                 SetCameraTriggerMode(cameras[i]);55                                 //2、设置具体的触发模式为软触发56                                 SetCameraTriggerSource(cameras[i]);57                                 cameras[i].MV_CC_RegisterImageCallBackEx_NET(_outputImageDelegate, i);58                             }59                         }60                     }61                 }

4、回调方法的实现。回调的方法可以根据自己的需求编写,这是我的需求,我的具体编写方法,不能照抄。

1      ///  2         /// 获取帧数据并保存为图像的回调函数。 3         ///  4         /// 图像的帧数据。 5         /// 图像的帧信息。 6         /// 相机的索引,因为有多台相机。 7         private void SaveImageCallBack(IntPtr frameData, ref MyCamera.MV_FRAME_OUT_INFO_EX frameInfo, IntPtr cameraIndex) 8         { 9             int _cameraIndex = (int)cameraIndex;10 11             if (_perCameraTotalFrames != null && _perCameraTotalFrames.Length > 0)12             {13                 //抓取的帧数14                 ++_perCameraTotalFrames[_cameraIndex];15 16                 //第一个相机数据,每台相机处理的数据是一样的,随机选择第一个,作为结果输出。17                 if (_cameraIndex == 0)18                 {19                     SetAsyncControlText(lblAcquisitionCountValue, _perCameraTotalFrames[_cameraIndex].ToString());20                 }21             }22 23             //显示图像 24             //将相机图像显示到对应的位置25             if (_imageDisplayHandles != null && _imageDisplayHandles.Length > 0)26             {27                 MyCamera.MV_DISPLAY_FRAME_INFO displayFrameInfo = new MyCamera.MV_DISPLAY_FRAME_INFO();28                 displayFrameInfo.hWnd = _imageDisplayHandles[_cameraIndex];29                 displayFrameInfo.pData = frameData;30                 displayFrameInfo.nDataLen = frameInfo.nFrameLen;31                 displayFrameInfo.nWidth = frameInfo.nWidth;32                 displayFrameInfo.nHeight = frameInfo.nHeight;33                 displayFrameInfo.enPixelType = frameInfo.enPixelType;34 35                 if (_myCameras != null && _myCameras.Length > 0)36                 {37                     CameraDisplayOneFrame(_myCameras[_cameraIndex], ref displayFrameInfo);38                 }39             }40 41             //判断当前相机是否允许保存图像42             if (_isPerCameraSaveImage != null && _isPerCameraSaveImage.Length > 0)43             {44                 if (_isPerCameraSaveImage[_cameraIndex] && _saveImageForCameraDirectory != null && _saveImageForCameraDirectory.Length > 0 && _perCameraSerialNumbers != null && _perCameraSerialNumbers.Length > 0)45                 {46                     MyCamera.MV_SAVE_IMG_TO_FILE_PARAM stSaveToFileParam = new MyCamera.MV_SAVE_IMG_TO_FILE_PARAM();47 48                     stSaveToFileParam.enPixelType = frameInfo.enPixelType;49                     stSaveToFileParam.pData = frameData;50                     stSaveToFileParam.nDataLen = frameInfo.nFrameLen;51                     stSaveToFileParam.nWidth = frameInfo.nWidth;52                     stSaveToFileParam.nHeight = frameInfo.nHeight;53 54                     stSaveToFileParam.enImageType = MyCamera.MV_SAVE_IAMGE_TYPE.MV_Image_Bmp;55                     stSaveToFileParam.nQuality = 100;56                     //图像文件名应包含采集时间、对应相机ID号、玻璃编号等信息57                     var saveImageFullPath = $"{_saveImageForCameraDirectory[_cameraIndex]}\\{DateTime.Now.ToString("yyyyMMddHHmmss")}_{_perCameraSerialNumbers[_cameraIndex]}_{_patrolFileGlassNumber}.bmp";58                     stSaveToFileParam.pImagePath = saveImageFullPath;59 60                     if (_myCameras != null && _myCameras.Length > 0)61                     {62                         _myCameras[_cameraIndex].MV_CC_SaveImageToFile_NET(ref stSaveToFileParam);63                         CameraSaveImageToFile(_myCameras[_cameraIndex], ref stSaveToFileParam);64                     }65                 }66             }67         }

三、总结我已经实验过单相机回调没问题了,所以多相机就直接复制了多个回调,因此相机回调还没传到外面的实例,就已经崩了,肯定就是封装的问题。看了海康的多相机demo,相机有4个实例,回调函数只有一个实例,4个相机注册了四次回调,但都是同一个回调实例。这就是我发生错误的根本原因。    好了,问题解决了,又学了点技术,继续努力,苍天不负努力的人。

标签:

【免责声明】

1、凡本网注明出处非(巨潮财经网)的作品,均转载于自其它媒体,并不代表本网赞同其观点和对其真实性负责,目的在于信息的传递,本网不承担稿件侵权行为的连带责任,如对稿件有质疑请与本网客服联系。

2、刊发此文目的在于传递更多信息,文章内容仅供参考,不构成投资建议,投资者据此操作,风险自担。

3、如涉及作品内容、版权等其它问题,请在15日内联系本网客服。

阅读延展

世界要闻:我在使用Winform7.0开发海康相机应用的时候系统悄无声息的退出

世界要闻:我在使用Winform7.0开发海康相机应用的时候系统悄无声息的退出

一、简介1、说明一下最近,我在开发一个玻璃幕墙检测的项目,这个项目

2023-06-29 17:29:25

群峰互联网_如何入驻群峰伙伴

群峰互联网_如何入驻群峰伙伴

吸引定律,简单来说就是好的想法和态度决定吸引更多好的东西给你,消极

2023-06-29 17:05:55

天天即时看!独家!甘肃350亿氢能项目招标方并非国家电投旗下公司

天天即时看!独家!甘肃350亿氢能项目招标方并非国家电投旗下公司

每经讯6月21日,中广通科技(酒泉)有限公司发布了4GW光伏离网制氢项目

2023-06-29 16:22:40

多家高校下月起停用微信支付,微信团队致歉:即刻修正

多家高校下月起停用微信支付,微信团队致歉:即刻修正

由于微信支付将收取0 6%的手续费,近期,全国多家高校发布公告称,自7

2023-06-29 16:13:59

国家金融监管总局批复!涉及大家财险多名高管任职资格 环球快报

国家金融监管总局批复!涉及大家财险多名高管任职资格 环球快报

6月29日消息,国家金融监管总局日前批复,核准林道大家财产保险有限责

2023-06-29 15:43:30

最近更新

世界要闻:我在使用Winform7.0开发海康相机应用的时候系统悄无声息的退出

世界要闻:我在使用Winform7.0开发海康相机应用的时候系统悄无声息的退出

一、简介1、说明一下最近,我在开发一个玻璃幕墙检测的项目,这个项目

2023-06-29 17:29:25

世纪佳缘邀您来组局,了解“搭子文化”

时代变迁,潮起潮落。在科技不断发展的今天,人们的生活观、价值观

2023-06-29 17:01:26

群峰互联网_如何入驻群峰伙伴

群峰互联网_如何入驻群峰伙伴

吸引定律,简单来说就是好的想法和态度决定吸引更多好的东西给你,消极

2023-06-29 17:05:55

找到你的搭子,志同道合的朋友世纪佳缘帮您搞定

饭搭子,旅行搭子,阅读搭子,游戏搭子……每个人都需要找到一个搭

2023-06-29 16:54:14

沈子瑜:星纪魅族集团以「手机域」开创融合发展新未来|全球热闻

沈子瑜:星纪魅族集团以「手机域」开创融合发展新未来|全球热闻

2023年6月28日至6月30日,2023MWC上海世界移动通信大会(简称「MWC上海

2023-06-29 16:44:01

自主新能源品牌加速出海 中金预计2023年乘用车出口有望超350万辆_天天聚看点

自主新能源品牌加速出海 中金预计2023年乘用车出口有望超350万辆_天天聚看点

中国自主新能源品牌出海步伐正在加快。6月29日,比亚迪巴西子公司负责

2023-06-29 16:52:11

上汽否认MG印度公司被低价收购

上汽否认MG印度公司被低价收购

上汽集团发布澄清声明否认旗下MG印度公司被当地强行低价收购。6月26日

2023-06-29 16:38:10

法英矿商将联手开发英国最大锂矿

法英矿商将联手开发英国最大锂矿

财经网汽车6月29日讯法国矿业集团Imerys将与英国的BritishLithium组建

2023-06-29 16:51:45

网贷无力偿还最坏结果是什么?网贷确实无力偿还怎么办

网贷无力偿还最坏结果是什么?网贷确实无力偿还怎么办

网贷无力偿还最坏结果是什么1、信用记录受损网络借贷属于信用贷款,逾期还款会影响个人信用记录。在银行或其他金融机构查询信...

2023-06-29 16:55:06

网贷无力偿还会被列为失信人吗?失信人员一辈子还不起怎么办

网贷无力偿还会被列为失信人吗?失信人员一辈子还不起怎么办

网贷无力偿还会被列为失信人吗欠下的网贷无法还清,借款方可能会将你列为失信人。这会对你的信用记录造成严重的影响,影响你...

2023-06-29 16:53:15

欠了网贷无力偿还怎么办?网贷逾期多久会被起诉

欠了网贷无力偿还怎么办?网贷逾期多久会被起诉

欠了网贷无力偿还怎么办首先,如果你欠下了网贷无力偿还,不要惊慌。应该冷静分析自己的情况,制定出一份还款计划。可以尝试...

2023-06-29 16:51:45

欠信用卡逾期了自救的办法是什么?信用卡逾期了怎么恢复

欠信用卡逾期了自救的办法是什么?信用卡逾期了怎么恢复

欠信用卡逾期了自救的办法是什么1 及时还款如果您欠了信用卡,应该尽快还款。如果您无法一次性还清,可以与银行协商制定还款...

2023-06-29 16:50:06

欠信用卡30万死了要家人还吗?信用卡逾期了无力偿还怎么办

欠信用卡30万死了要家人还吗?信用卡逾期了无力偿还怎么办

欠信用卡30万死了要家人还吗要还。根据中国法律,如果债务人去世,债务应该由遗产来偿还。如果遗产不足以偿还债务,家人是不...

2023-06-29 16:47:49

欠信用卡30万死了怎么办?欠信用卡30万要判几年

欠信用卡30万死了怎么办?欠信用卡30万要判几年

欠信用卡30万死了怎么办1 及时通知银行如果您欠了信用卡30万,无法偿还,应该及时通知银行。银行会根据您的情况,给出相应的...

2023-06-29 16:46:23

网商贷的钱还不起了会承担刑事责任吗?网商贷的钱还不起了怎么办

网商贷的钱还不起了会承担刑事责任吗?网商贷的钱还不起了怎么办

网商贷的钱还不起了会承担刑事责任吗借款人存在欺诈行为将面临刑事责任。但是,如果借款人是因为自身原因无法按时还款,不会...

2023-06-29 16:44:43

天天即时看!独家!甘肃350亿氢能项目招标方并非国家电投旗下公司

天天即时看!独家!甘肃350亿氢能项目招标方并非国家电投旗下公司

每经讯6月21日,中广通科技(酒泉)有限公司发布了4GW光伏离网制氢项目

2023-06-29 16:22:40

网商贷的钱还不起可以报警吗?网商贷还不起做多久牢

网商贷的钱还不起可以报警吗?网商贷还不起做多久牢

网商贷的钱还不起可以报警吗借款人无法与网商贷客服协商解决问题,可以向公安机关报案。但是,报案前需要先确认自己是否存在...

2023-06-29 16:41:58

网商贷的钱还不起了怎么办?网贷还不起了怎么办

网商贷的钱还不起了怎么办?网贷还不起了怎么办

网商贷的钱还不起了怎么办借款人无法按时还款,首先应该尽快与网商贷的客服联系,说明自己的情况,并请求延期还款或者分期还...

2023-06-29 16:40:25

网贷协商还款需要准备什么材料?网贷如何协商延期还款

网贷协商还款需要准备什么材料?网贷如何协商延期还款

网贷协商还款需要准备什么材料1 贷款合同:需要提供贷款合同的原件或复印件,以便确认欠款金额和还款期限等信息。2 身...

2023-06-29 16:38:27

网贷协商还款对信用有影响吗?网贷协商还本金技巧是什么

网贷协商还款对信用有影响吗?网贷协商还本金技巧是什么

网贷协商还款对信用有影响吗网贷协商还款对信用有一定的影响。如果你按照协商的还款方式还款,那么这种还款方式会被记录在你...

2023-06-29 16:36:10

网贷怎么协商还款?债务委托延期还款是真的吗

网贷怎么协商还款?债务委托延期还款是真的吗

网贷怎么协商还款1 延期还款:可以与网贷公司协商,将还款日期延后一段时间,以减轻还款压力。2 分期还款:可以与网贷...

2023-06-29 16:34:11

网贷爆通讯录报警有用吗?永远不接催收电话后果是什么

网贷爆通讯录报警有用吗?永远不接催收电话后果是什么

网贷爆通讯录报警有用吗有用。个人信息被泄露,导致骚扰电话的数量非常多,那么你可以考虑报警。因为这是一种有效的维权手段...

2023-06-29 16:32:10

网贷爆通讯录删除通讯录有用吗?网贷逾期五六年催收有用吗

网贷爆通讯录删除通讯录有用吗?网贷逾期五六年催收有用吗

网贷爆通讯录删除通讯录有用吗有用,但不能完全解决问题。因为网贷公司可能已经将你的个人信息上传到了其他的平台,或者将你...

2023-06-29 16:29:18

网贷现在还爆通讯录吗?网贷逾期了暂时还不上怎么办

网贷现在还爆通讯录吗?网贷逾期了暂时还不上怎么办

网贷现在还爆通讯录吗这种情况在过去确实存在过,但是现在已经得到了有效的遏制。首先,现在的网贷公司都有比较完善的信息保...

2023-06-29 16:29:15

快播:太和水:
截止5月31日,公司股东户数为13,079

快播:太和水: 截止5月31日,公司股东户数为13,079

太和水(605081)06月29日在投资者关系平台上答复了投资者关心的问题。

2023-06-29 16:05:20

csgo开箱系统要钱吗?csgo开箱子多少钱一次

csgo开箱系统要钱吗?csgo开箱子多少钱一次

作为csgo老玩家,相信很多人都知道这款游戏里开箱获取的是皮肤饰品等可以在游戏中跟玩家之间互相交易,因此这里面就存在理财...

2023-06-29 16:23:25

csgo开箱网站赚钱吗?csgo开箱主播好当吗

csgo开箱网站赚钱吗?csgo开箱主播好当吗

CSGO网站开箱全透明几率,保底出货,红色手套,金色巨龙传说开箱即有几率获取。与众不同的花式贴纸,造型炫酷的匕首外观,开...

2023-06-29 16:20:02

csgo开箱靠谱吗?csgo开箱如何出金

csgo开箱靠谱吗?csgo开箱如何出金

现在市面上的开箱平台有非常多,许多玩家都跃跃欲试,想成为那个一夜暴富的欧皇,那么哪个csgo开箱平台出传说皮肤概率高呢,...

2023-06-29 16:15:32

价格战开启,6月多家银行理财宣布产品费率“打折”

价格战开启,6月多家银行理财宣布产品费率“打折”

界面新闻记者|韩宇航界面新闻编辑|继招银理财发售“不赚钱不收管理费”

2023-06-29 16:03:02

A股收评:三大指数震荡整理,机器人概念掀涨停潮

A股收评:三大指数震荡整理,机器人概念掀涨停潮

两市共3350股上涨,全日成交8650亿元。

2023-06-29 15:55:25