VisionPro二次开发学习笔记1-创建基于QuickBuild的C#应用程序

news2024/11/24 12:55:45

创建基于QuickBuild的C#应用程序

使用的QuickBuild应用程序位于%VPRO_ROOT%/ Samples / Programming / QuickBuild / advancedAppOne.vpp中。在继续之前,可以在QuickBuild中运行该应用程序。

QuickBuild应用程序使用PatMax查找支架的“耳朵”之一,使用CogFixture工具设置图像的坐标空间,使用Blob工具查找两个中心孔,并使用CogDistancePointToPointTool测量孔之间的距离。最后,结果分析工具通过测试两个孔之间的距离是否在可接受的范围内来确定检查是否通过。

该指南分为四个步骤:

  1. 加载QuickBuild应用程序
  2. 添加GUI并使用线程
  3. 增强GUI并显示结果
  4. 显示影像

1.加载QuickBuild应用程序

1. 打开Visual Studio,创建一个C#.NetFramework的Windows应用程序.
2. 添加以下引用
  • Cognex.VisionPro
  • Cognex.VisionPro.Core
  • Cognex.VisionPro.QuickBuild.Core
3. 打开Form1.cs,添加代码如下:
using Cognex.VisionPro;
using Cognex.VisionPro.QuickBuild;
4. 声明变量
private CogJobManager myJobManager;
private CogJob myJob;
private CogJobIndependent myIndependentJob;
5. 在窗体Load事件中加载QuickBuild 应用程序
/// <summary>
/// 从一个文件中加载作业管理器对象。
/// 获取该管理器中的第一个作业。
/// 从该作业中获取与之关联的独立作业。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
        {
            myJobManager = CogSerializer.LoadObjectFromFile(Environment.GetEnvironmentVariable("VPRO_ROOT")+"\\Samples\\Programming\\QuickBuild\\advancedAppOne.vpp") as CogJobManager;

            myJob = myJobManager.Job(0);
            myIndependentJob = myJob.OwnedIndependent;

            //确保队列为空:
            //在加载一个 VisionPro 持久化文件时,需要确保所有队列都是空的。这是因为加载的过程会精确地重建保存时的对象状态。如果在加载过程中队列中仍然保留着未处理的数据,这可能会导致不一致或错误的行为。
            //冲洗队列:
            //“冲洗所有队列”意味着清空所有待处理的数据,以确保系统在加载新的作业或状态时处于一个干净的状态。这种做法是为了避免在处理新数据时与旧数据发生冲突,从而确保系统的稳定性和可靠性。
            myJobManager.UserQueueFlush();
            myJobManager.FailureQueueFlush();
            myJob.ImageQueueFlush();
            myIndependentJob.RealTimeQueueFlush();
        }
6. 关闭

QuickBuild 应用程序的 CogJobManager 对象在运行时会创建多个线程。关闭 CogJobManager 是非常重要的。

当窗体关闭时,将调用 Form1_FormClosing 方法。

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {            
            myJobManager.Shutdown();
        }

2. 添加GUI并使用线程

1. 创建一次运行按钮

您将添加的第一个用户界面元素是运行已保存的QuickBuild应用程序的按钮。在Visual Studio工具箱中,将“按钮”从“公共控件”部分拖到Form1。将此按钮命名为RunOnceButton并将其文本设置为Run一次。

双击按钮以创建其Click处理程序,然后键入以下代码:

private void RunOnceButton_Click(object sender, EventArgs e)
        {
            try
            {
                
                myJobManager.Run();
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
        }

Run方法在myJobManager中运行所有作业,其中包含已保存的QuickBuild应用程序。按钮的Click处理程序在Try / Catch块内调用Run,以处理QuickBuild应用程序开始运行时可能发生的任何错误。

立即运行程序,然后单击“运行一次”按钮以运行应用程序。(由于此时您未显示任何输出,因此您将看不到任何内容。)尝试尽快重复单击RunOnce按钮。您应该收到一条错误消息。

2. 处理作业事件

快速单击“运行一次”按钮时出现错误的原因是“运行”是立即返回的异步方法。如果在作业运行时再次调用它。您会收到CogNotStoppedException错误。

为避免此问题,您将在作业运行时禁用“运行一次”按钮,并在作业停止时重新启用它。在作业开始时禁用按钮非常容易。您所需要做的就是禁用其Click处理程序中的按钮:

private void RunOnceButton_Click(object sender, EventArgs e)
        {
            try
            {
                RunOnceButton.Enabled = false;
                
                myJobManager.Run();
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
        }

在作业停止运行时重新启用按钮会稍微复杂一些。当作业管理器中的所有作业均已完成运行时,CogJobManager会触发Stopped事件。您将把代码重新放入作业管理器的Stopped事件处理程序中的按钮。

在Form1类的末尾,为作业管理器编写Stopped处理程序,如下所示:

private void MyJobManager_Stopped(object sender, CogJobManagerActionEventArgs e)
        {
           
            RunOnceButton.Enabled = true;
            
        }

定义了Stopped事件处理程序后,需要确保作业管理器知道它在哪里。使用AddHandler注册事件的处理程序。AddHandler的第一个参数是事件;第二个参数是处理程序的地址。将以下代码添加到Form1_Load方法的末尾:

 //注册停止事件
            myJobManager.Stopped += MyJobManager_Stopped;

每当您注册事件处理程序时,最好在关闭程序之前将其删除。在此示例中,执行此操作的最佳位置是在关闭作业管理器之前的窗体的FormClosing处理程序中。现在,FormClosing处理程序应如下所示:

 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            myJobManager.Stopped -= MyJobManager_Stopped;
           
            myJobManager.Shutdown();

        }

如果此时运行程序,则会出现错误:跨线程操作无效。

3.处理跨线程函数调用

请记住,作业管理器会创建多个线程。这些线程之一触发运行已停止事件处理程序的Stopped事件,并最终尝试重新启用“运行一次”按钮。此事件序列是非法的,因为按钮-或任何其他Microsoft Windows Forms控件-只能由创建该控件的线程访问。该按钮不是由任何作业管理器线程创建的。

Microsoft提供了一种对控件进行线程安全调用的方法。

注意:您可以在此MDSN文章中了解有关进行线程安全调用的更多信息。

每个控件都有一个InvokeRequired属性,如果正在从未创建控件的线程中调用它,则该属性返回True。如果为True,则必须创建一个指向将访问该控件的函数的指针,切换到创建该控件的线程,然后使用该指针再次调用该函数。

在.NET中,指向函数的指针是委托。您将声明一个与您要处理的事件具有相同功能签名(参数)的委托。在这种情况下,您的委托人具有与Stopped事件相同的签名。在Stopped事件处理程序之前添加以下代码行:

private delegate void myJobManagerDelegate(object sender,CogJobManagerActionEventArgs e);

现在,在Stopped事件处理程序中,您将检查是否从错误的线程调用了该处理程序。如果是这样,则将使用定义的委托创建指向处理程序的指针,然后使用Invoke方法以递归方式调用它。这是Stopped事件处理程序的外观:

 private void MyJobManager_Stopped(object sender, CogJobManagerActionEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myJobManagerDelegate(MyJobManager_Stopped),new object[] { sender,e});
                return;
            }
            RunOnceButton.Enabled = true;
            
        }

3. 增强GUI并显示结果

1. 添加连续运行按钮

您将添加的下一个用户界面元素是“运行连续”按钮。当您单击此按钮时,它将保持按下状态,并且该应用程序将运行,直到再次单击该按钮。若要获得此行为,本示例使用一个复选框并将其外观更改为按钮。

确保Form1.cs [设计]选项卡处于活动状态。从Visual Studio工具箱的“公共控件”部分中,将一个CheckBox控件拖到窗体上。将其文本更改为“连续运行”。将其名称更改为RunContCheckBox。最后,将其外观更改为Button。

双击新的“连续运行”按钮以创建其Check_Changed处理程序,并添加以下代码:

private void RunContentCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (RunContentCheckBox.Checked)
            {
                try
                {
                    
                    myJobManager.RunContinuous();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else
            {
                try
                {
                    
                    myJobManager.Stop();
                }
                catch (Exception ex)
                {

                    MessageBox.Show(ex.Message);
                }
            }
            
        }

RunContinuous方法重复运行myJobManager中的所有作业,该作业包含您保存的QuickBuild应用程序,直到Stop停止它们为止。CheckedChanged处理程序负责在作业开始时禁用“运行一次”按钮,并在等待作业停止时禁用“连续运行”按钮。

将以下代码行添加到“已停止”处理程序中,以在所有作业停止后重新启用“连续运行”按钮。

 private void MyJobManager_Stopped(object sender, CogJobManagerActionEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myJobManagerDelegate(MyJobManager_Stopped),new object[] { sender,e});
                return;
            }
            RunOnceButton.Enabled = true;
            RunContentCheckBox.Enabled = true;
        }

并将以下代码行添加到“运行一次”按钮的单击处理程序,以在作业运行一次时禁用“连续运行”按钮。

RunContentCheckBox.Enabled = false;

如果此时运行程序,则会在适当的时间看到按钮变为启用和禁用状态。您也可以单击窗口的关闭框以退出应用程序,即使该应用程序正在运行。

2. 显示程序结果

当用户队列中有新结果可用时,作业管理器将触发UserResultAvailable事件。在那儿,您将从工作中提取数据并将其显示在表单中。

确保Form1.cs [设计]选项卡处于活动状态。从Visual Studio工具箱的“公共控件”部分中,将一个TextBox拖到您的窗体上。将其名称更改为RunStatusTextBox。在这里您将显示应用程序的运行状态。

在Form1类的末尾,添加以下UserResultAvailable事件处理程序。请注意,由于它修改了用户界面项(文本框),因此您需要使用之前学习的Invoke习惯用法。

 private void MyJobManager_UserResultAvailable(object sender, CogJobManagerActionEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myJobManagerDelegate(MyJobManager_UserResultAvailable), new object[] { sender, e });
                return;
            }
            ICogRecord topRecord = myJobManager.UserResult();
            RunStatusTextBox.Text = topRecord.SubRecords["UserResultTag"].Content + ":" + topRecord.SubRecords["JobName"].Content + "-->" + topRecord.SubRecords["RunStatus"].Content.ToString();

           
        }

UserResult方法从作业管理器的用户队列中删除并返回最早的结果记录。该记录包含“已发布项目”列表中每个项目的子记录。它还包含这些其他子记录:

UserResultTag

作业运行的序列号
职位名称

返回结果的作业的名称
运行状态

作业的RunStatus

在运行程序之前,您需要在窗体的Load处理程序中注册UserResultsAvailable处理程序,然后在其FormClosing处理程序中注销它。现在,Load处理程序应如下所示:

private void Form1_Load(object sender, EventArgs e)
        {
            myJobManager = CogSerializer.LoadObjectFromFile(Environment.GetEnvironmentVariable("VPRO_ROOT")+"\\Samples\\Programming\\QuickBuild\\advancedAppOne.vpp") as CogJobManager;

            myJob = myJobManager.Job(0);
            myIndependentJob = myJob.OwnedIndependent;

            //确保队列为空:
            //在加载一个 VisionPro 持久化文件时,需要确保所有队列都是空的。这是因为加载的过程会精确地重建保存时的对象状态。如果在加载过程中队列中仍然保留着未处理的数据,这可能会导致不一致或错误的行为。
            //冲洗队列:
            //“冲洗所有队列”意味着清空所有待处理的数据,以确保系统在加载新的作业或状态时处于一个干净的状态。这种做法是为了避免在处理新数据时与旧数据发生冲突,从而确保系统的稳定性和可靠性。
            myJobManager.UserQueueFlush();
            myJobManager.FailureQueueFlush();
            myJob.ImageQueueFlush();
            myIndependentJob.RealTimeQueueFlush();

            //注册停止事件
            myJobManager.Stopped += MyJobManager_Stopped;
            myJobManager.UserResultAvailable += MyJobManager_UserResultAvailable;

            


        }

FormClosing处理程序如下所示:

//取消注册与 myJobManager 相关的事件处理程序,以避免在窗体关闭后接收事件。
        //调用 Application.DoEvents() 来处理任何挂起的消息,确保在执行后续操作(如关闭作业管理器)时,应用程序不会冻结。
        //调用 myJobManager.Shutdown() 方法以正确清理资源和停止后台任务。
        //使用 DoEvents() 可以确保在执行 Shutdown 操作之前,所有与用户界面相关的事件都得到处理,从而提高用户体验。尽管 DoEvents() 在某些情况下有其用途,但在大多数情况下,过度使用可能会导致复杂性增加,因此应谨慎使用。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            myJobManager.Stopped -= MyJobManager_Stopped;
            myJobManager.UserResultAvailable -= MyJobManager_UserResultAvailable;
            Application.DoEvents();
            myJobManager.Shutdown();

           
        }

除了删除UserResultAvailable处理程序外,FormClosing方法还调用Application.DoEvents()来清除Windows消息队列。它可以防止在单击表单的关闭框之后但未注册UserResultAvailable处理程序之前,如果有新的用户结果可用,则可能发生死锁。

3. 运行应用程序

运行应用程序时,您将在文本框中看到结果。在下一步中,您将在应用程序中添加一个显示。

4. 显示图像

  • 使用显示控件显示结果记录
  • 访问适当的记录以显示
  • 将显示状态栏连接到显示器
1. 显示控件概述

VisionPro提供了四种显示控件,可用于显示图像和图形。

显示控制描述
CogToolDisplay这是您在QuickBuild和视觉工具中看到的显示控件。您可以将VisionPro工具连接到显示控件,并直接从该工具提取记录。它使用下拉列表选择要显示的图像记录。
CogRecordsDisplay此控件类似于CogToolDisplay控件。它使用户可以从下拉列表中选择图像记录,并显示图像的任何图形子记录。与CogToolDisplay不同,此控件对VisionPro工具一无所知。您必须提供要显示的记录。
CogRecordDisplay该控件显示单个图像记录及其图形子记录。它没有下拉列表框,并且不允许用户选择图像。
CogDisplay这是所有其他显示控件用作基础的最低级别的显示控件。此控件显示单个图像和一组图形,这些图形必须直接提供给该控件。

在此示例中,您将使用CogRecordDisplay控件显示LastRun.CogFixtureTool1.OutputImage记录,其中包含括号的图像以及显示孔之间距离的图形。

添加对以下程序集的引用:

  • Cognex.VisionPro.Controls
  • Cognex.VisionPro.Display.Controls

确保Form1.cs [设计]选项卡处于活动状态。从Visual Studio工具箱的VisionPro显示控件部分中,将CogRecordDisplay控件拖到窗体上。

注意:如果在工具箱中看不到CogRecordDisplay,请在工具箱中单击鼠标右键,然后选择“选择项目”。在出现的“选择工具箱项”对话框中,向下滚动直到找到CogRecordDisplay并确保已选中该复选框。

在FormClosing方法的末尾,添加以下代码以在应用程序关闭时处置控件:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            myJobManager.Stopped -= MyJobManager_Stopped;
            myJobManager.UserResultAvailable -= MyJobManager_UserResultAvailable;
            Application.DoEvents();
            myJobManager.Shutdown();

            cogDisplayStatusBarV21.Dispose();
            cogRecordDisplay1.Dispose();
        }

然后在Load方法的末尾添加以下代码,以将显示状态栏与显示器链接起来。

private void Form1_Load(object sender, EventArgs e)
        {
            myJobManager = CogSerializer.LoadObjectFromFile(Environment.GetEnvironmentVariable("VPRO_ROOT")+"\\Samples\\Programming\\QuickBuild\\advancedAppOne.vpp") as CogJobManager;

            myJob = myJobManager.Job(0);
            myIndependentJob = myJob.OwnedIndependent;

            //确保队列为空:
            //在加载一个 VisionPro 持久化文件时,需要确保所有队列都是空的。这是因为加载的过程会精确地重建保存时的对象状态。如果在加载过程中队列中仍然保留着未处理的数据,这可能会导致不一致或错误的行为。
            //冲洗队列:
            //“冲洗所有队列”意味着清空所有待处理的数据,以确保系统在加载新的作业或状态时处于一个干净的状态。这种做法是为了避免在处理新数据时与旧数据发生冲突,从而确保系统的稳定性和可靠性。
            myJobManager.UserQueueFlush();
            myJobManager.FailureQueueFlush();
            myJob.ImageQueueFlush();
            myIndependentJob.RealTimeQueueFlush();

            //注册停止事件
            myJobManager.Stopped += MyJobManager_Stopped;
            myJobManager.UserResultAvailable += MyJobManager_UserResultAvailable;

            cogDisplayStatusBarV21.Display = cogRecordDisplay1;


        }

获取记录以显示在CogRecordDisplay控件中的代码位于UserResultAvailable处理程序的末尾:

private void MyJobManager_UserResultAvailable(object sender, CogJobManagerActionEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myJobManagerDelegate(MyJobManager_UserResultAvailable), new object[] { sender, e });
                return;
            }
            ICogRecord topRecord = myJobManager.UserResult();
            RunStatusTextBox.Text = topRecord.SubRecords["UserResultTag"].Content + ":" + topRecord.SubRecords["JobName"].Content + "-->" + topRecord.SubRecords["RunStatus"].Content.ToString();

            ICogRecord tmpRecord = topRecord.SubRecords["ShowLastRunRecordForUserQueue"];
            tmpRecord = tmpRecord.SubRecords["LastRun"];
            tmpRecord = tmpRecord.SubRecords["CogFixtureTool1.OutputImage"];
            cogRecordDisplay1.Record = tmpRecord;
            cogRecordDisplay1.Fit(true);
        }

对SubRecords的连续调用遵循子记录路径,以获取QuickBuild应用程序的Fixture工具的输出图像。Record属性指定要显示的记录。Fit方法缩放图像及其图形以适合显示控件。

界面设计如下:

在这里插入图片描述

如果立即运行该程序,您将看到CogRecordDisplay控件中显示的每个图像。

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1995446.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSH 和 Telnet 之间的区别

SSH 和 Telnet是帮助用户与远程系统建立连接的两种通信协议&#xff0c;这些通信协议决定了数据如何在网络上的不同设备之间传输&#xff0c;这些设备通常需要通过各种物理和数字环境进行传输&#xff0c;网络协议的主要目标是通信、网络管理和安全。 Telnet Telnet是一种较旧…

如果您的照片从设备中消失请无需惊慌,几个安卓照片恢复工具可以试试

新的手机数据恢复应用程序定期推出&#xff0c;这个市场竞争非常激烈。因此&#xff0c;选择最好的 Android 手机照片恢复应用程序可能是最棘手的部分。这就是为什么我们准备了一份概述&#xff0c;介绍目前被认为是恢复丢失照片最有效的应用程序。 几个安卓照片恢复工具 让我…

Cocos通过Electron打包web应用后,在触屏一体机设备触摸滑动无效问题解决

Cocos通过Electron打包web应用后&#xff0c;在触屏一体机设备触摸滑动无效问题解决 已经很晚了&#xff0c;刚刚解决这个问题&#xff0c;还是想记录一下&#xff0c;因为刚刚接触 cocos 没多久&#xff0c;这个问题困扰了我很久。 背景 接手了一个答题小游戏&#xff0c;由于…

直线度测量仪测量不准时如何快速自检恢复?

直线度测量仪应用于圆形产品的直线度及外径尺寸检测&#xff0c;既有应用于生产线中的在线测量仪又有离线直线度测量仪&#xff0c;但不管哪种设备&#xff0c;都是光学检测设备&#xff0c;也都具备光学设备的特性。 在测量仪的长期使用过程中&#xff0c;难免会遇到测量不准…

2015款到18款奔驰GLC升级为2021款的HU6主机后,实现了触摸屏人机交互和Carplay功能

奔驰GLC是北京奔驰生产的一款中型SUV。有车主将2015款奔驰GLC升级为2021款的HU6主机后&#xff0c;实现了触摸屏人机交互和Carplay功能。该车主分享了使用体验&#xff1a; • Carplay功能&#xff1a;可以直接在车机大屏幕上显示导航、音乐和电话信息&#xff0c;让用户在开车…

中国信息学奥赛专用系统之----NOI Linux 2.0系统安装教程

1、下载NOI Linux 2.0系统&#xff0c;下载地址&#xff1a; https://noiresources.ccf.org.cn/ubuntu-noi-v2.0.iso 2、新建虚拟机 3、开机安装系统 下载插件&#xff0c;可能需要10分钟以上。 5、进系统看看 OK,NOI Linux 2.0系统安装完毕&#xff01;

MySQL面试题全解析:准备面试所需的关键知识点和实战经验

MySQL有哪几种数据存储引擎&#xff1f;有什么区别&#xff1f; MySQL支持多种数据存储引擎&#xff0c;其中最常见的是MyISAM和InnoDB引擎。可以通过使用"show engines"命令查看MySQL支持的存储引擎。 存储方式&#xff1a;MyISAM引擎将数据和索引分别存储在两个不…

手机怎么远程控制电脑屏幕?手机远程控制电脑方法分享

手机与电脑之间的互联互通变得越来越便捷。 无论是工作还是学习&#xff0c;有时我们需要在手机上远程控制电脑屏幕&#xff0c;以完成一些复杂的操作或查看电脑上的文件。 本文将详细介绍几种实用的手机远程控制电脑屏幕的方法&#xff0c;帮助读者轻松实现这一目标。 一、使…

美容院节假日可以做哪些营销活动?博弈美业系统源码|美容院管理系统

美容院在节假日期间开展各种类型的营销活动是必不可少的&#xff0c;可以吸引用户消费或充值、开发新客户、提高客户忠诚度。 在举办各类活动时&#xff0c;可针对不同的用户群体采取不同的活动策略&#xff0c;下面给大家简单列举一些活动策略&#xff0c;门店可在此基础上根…

【Nessus破解及20220412插件】漏洞扫描工具之一,windows版本安装

一、双击安装程序 安装路径默认即可&#xff0c;记住安装的路径在哪里。 一般默认路径都是——C:\Program Files\Tenable\Nessus 等待初始化加载完成。 选择第四个。 选择Tenable.sc&#xff0c;继续下一步。 填写username和密码继续。 安装完是以下界面&#xff0c;目前还不能…

【机器学习之深度学习】神经元、层的基本概念,神经网络以及神经元与线性回归和逻辑回归的相似之处

引言 神经元、层和神经网络是深度学习模型的核心组成部分&#xff0c;它们共同工作&#xff0c;使得深度学习能够处理复杂的数据和任务。通过叠加多个层&#xff0c;可以构建出能够学习复杂函数的深度神经网络 一、神经元和层 深度学习中的神经元和层是构建复杂预测模型的基础…

Unity 使用字符串更改Text指定文字颜色、大小、换行、透明

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、使用字符串改变文字属性的方法&#xff08;一&#xff09;修改颜色&#xff08;二&#xff09;修改大小&#xff08;三&#xff09;换行&#xff08;四&…

SQL注入实例(sqli-labs/less-15)

0、初始页面 1、确定闭合符号 确定符号的闭合 2、爆库名 python脚本爆库名 def inject_database(url):name for i in range(1,20):low 32high 128while low < high:mid (low high) // 2payload "-1 or ascii(substr(database(),%d,1))>%d # " %(i,mid…

从今天开始深入学习 SQL 优化

SQL优化 .SQL优化12.1 selet具体字段 12.2 多用limit 12.3 用union all替换 union 12.4 优化group by 12.5 优化order by 12.6 小表驱动大表 12.7 字段类型使用合理 12.8 优化linit分页 12.9 exist& in的合理利用 12.10 join关联的表不宜过多 12.11 deletein自查询不走索引…

学习记录——day29 网络编程

目录 一、网络编程引入 1.1、IPC通信方式 1&#xff09;内核提供&#xff1a; 无名管道 有名管道 信号 2&#xff09;system V: 消息队列 共享内存 信号量集 1.2、网络通信使用缘由 二、网络发展阶段 2.1 APRAnet阶段 2.2 TCP/IP两个协议阶段…

Java收发邮件笔记

1 关于邮箱的前置知识 1.1 概念部分 邮箱服务器和协议是电子邮件系统中不可或缺的两个组成部分&#xff0c;它们共同确保了电子邮件的顺利发送、接收和管理。 1.1.1 服务器和协议 邮箱服务器 比如常见的QQ邮箱,网易邮箱。 邮箱服务器是一种负责电子邮件收发管理的计算机系…

Rust学习---Hello World

编写 Rust 程序 1.程序文件后缀名: rs 2.文件命名规范:hello_world.rs 3.(例子) 使用命令创建项目&#xff0c;命名为"hello world" 打开 cmd 输入: mkdir hello_world cd hello_world 新建文件 main.rs编译与运行 Rust 程序 1.编译:rustc main.rs&#xff0c;…

【无标题】Unity Asset Hunter 插件

Asset Hunter PRO是Unity的一款插件&#xff0c;用于分析工程内的资源使用情况&#xff0c;资源大小&#xff0c;分析资源依赖关系&#xff0c;可以用来清理项目中未使用的资源。尤其是项目较大时&#xff0c;删除没有使用的资源很有帮助。 对于项目UI图片修改次数过多时&…

Linux 进程概念

Linux 进程概念 硬件理解冯 诺依曼体系结构五大组成部件强调存储 引子操作系统&#xff08;Operator System&#xff09;概念作用认识为什么要有操作系统&#xff1f; 结构 示意图理解操作系统system call库函数概念 进程什么是进程概念误区认识 描述进程 - PCBtask_struct - P…

colResizable插件实现网页中表格列宽自定义

需求&#xff1a;页面上每个字段的列宽&#xff0c;可以通过页面拖动的形式进行调整。 解决方法&#xff1a;使用jQuery的一个插件&#xff0c;名称叫 colResizable&#xff0c;可以实现。 插件官网 colResizable – 可调整大小的列和表 (bacubacu.com) 说明&#xff1a; 该…