首页
归档
友情链接
留言
更多
关于
动态
Search
1
[分享栈]centos7安装gcc10.2.0
7,215 阅读
2
[技术栈]CRC校验原理及C#代码实现CRC16、CRC32计算FCS校验码
6,754 阅读
3
[技术栈]C#利用Luhn算法(模10算法)对IMEI校验
6,338 阅读
4
[分享栈]esxi6.7虚拟机安装omv(openmediavault)教程
5,973 阅读
5
[分享栈]centos7安装python3.8.5
4,880 阅读
分享栈
技术栈
经验栈
登录
Search
标签搜索
C#
centos
winform
仪器
IPV4
IPV6
测速
crc
crc16
crc32
fcs
luhn
模10
算法
sql
gcc
python
紫光展锐
omv
openmediavault
武小栈
累计撰写
21
篇文章
累计收到
36
条评论
首页
栏目
分享栈
技术栈
经验栈
页面
归档
友情链接
留言
关于
动态
搜索到
8
篇与
的结果
2021-02-04
[分享栈]winform根据控件name获取到控件对象
1. 前言今天武小栈接到了一个产线工具一拖多的更改需求,就引出了今天的总结,C#开发winform项目根据控件name获取到控件对象。2. 正文查看Form.ControlCollection类可以看到提供了两种方法:2.1 Item属性Label label = this.Controls["label"+(i+1)] as Label;2.2 Find方法Label label = this.Controls.Find("label" + (i + 1),true)[0] as Label3. 注意Find()函数这里第二个参数为bool型,指定是否在所有子类控件中查找。这里引出了第一种方式查找控件仅在当前控件的第一代子控件查找,第二种方式当第二个参数为true时,在所有代子类中查找控件,我这里猜一下里面是一个嵌套循环。根据实际需求选择即可。
2021年02月04日
1,107 阅读
0 评论
0 点赞
2020-07-13
[经验栈]C#中几种定时器(timer)的区别
[TOC]1、前言 不知道你是否对.NET里面的定时器产生过一些疑问,以下是武小栈个人的一些总结。2、官方介绍在.NET的框架之内定时器有四种,先看一下微软官方对他们各自特点介绍:System.Timers.Timer,它将触发事件,并定期在一个或多个事件接收器中执行代码。 类旨在用作多线程环境中基于服务器的组件或服务组件;它没有用户界面,在运行时不可见。System.Threading.Timer,它按固定的时间间隔对线程池线程执行单个回调方法。 回调方法是在实例化计时器时定义的,无法更改。 与 System.Timers.Timer 类一样,此类用作多线程环境中基于服务器的或服务组件;它没有用户界面,在运行时不可见。System.Windows.Forms.Timer (仅 .NET Framework),这是一个触发事件并定期在一个或多个事件接收器中执行代码的 Windows 窗体组件。 组件没有用户界面,旨在在单线程环境中使用;它在 UI 线程上执行。System.Web.UI.Timer (仅 .NET Framework),是一种定期执行异步或同步网页回发的 ASP.NET 组件。再看看微软对开发者的使用建议:System.Threading.Timer 是一种简单的轻型计时器,它使用回调方法,并由线程池线程提供服务。 不建议与 Windows 窗体一起使用,因为它的回调不会在用户界面线程上发生。 System.Windows.Forms.Timer 是用于 Windows 窗体的更好选择。 对于基于服务器的计时器功能,您可以考虑使用 System.Timers.Timer,这会引发事件并具有其他功能。3、个人体会System.Threading.Timer Class是一个基础类,使用起来不是太好用,各种用法较为原始,用的较少。System.Windows.Forms.Timer Class第一次接触的就是它,毕竟直接winform拖下来就行了,用的还是比较多,我通常用在运行一些刷新界面的代码,这些代码通常不会有什么逻辑运算,比如界面上需要显示一个倒计时。在这个类使用中我遇到过两个疑惑,作为分享:Q1:Tick实践会创建新线程执行吗?A1:不会创建新的线程,始终在主线程里面运行Tick事件;Q2:定时器会start()瞬间触发一次,还是等待Interval间隔后再触发?A2:等待Interval间隔后再触发。Q3:定时器start()和stop()时候Interval会累积吗?A3:不累积,每次start()重新计时。Q4:如果Tick事件内的代码未执行完成,但是下一次Tick定时已经达到会发生什么?A4:不会强行终止未完成的代码,也不会因为上一次Tick事件代码未执行完成而不再触发,而是类似于栈的形式将之前未执行完成的代码堆积,后触发的Tick事件内的代码先执行,先触发未完成的代码后执行,具体可以看下面示例。 public Form1() { InitializeComponent(); timerForm.Tick += TimerForm_Tick; } private int num = 1;//一个序号,表示当前第几次进入Tick事件 private int rowNum = 1;//一个全局的行号,记录一下总共AppendText多少次 private void TimerForm_Tick(object sender, EventArgs e) { string s = $"我是第{num++}次"; for (int i = 0; i < 5; i++) { textBox1.AppendText($"{rowNum++} {s} 序号i={i} 当前线程ID={Thread.CurrentThread.ManagedThreadId.ToString()} \r\n"); Delay(1000); } } private Timer timerForm = new Timer(){Interval = 1000}; private void button1_Click(object sender, EventArgs e) { textBox1.AppendText("button " + Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n"); timerForm.Start(); } public static void Delay(int mimillisecond) { int start = Environment.TickCount; while (Math.Abs(Environment.TickCount - start) < mimillisecond) { System.Windows.Forms.Application.DoEvents(); } }System.Timers.Timer Class 是对System.Threading.Timer的一层封装,都是通过委托方法TimerCallback进行回调触发定时器事件,可以先看看System.Timers.Timer的代码实现方式: if (!value) { if (this.timer != null) { this.cookie = (object) null; this.timer.Dispose(); this.timer = (System.Threading.Timer) null; } this.enabled = value; } else { this.enabled = value; if (this.timer == null) { if (this.disposed) throw new ObjectDisposedException(this.GetType().Name); int dueTime = (int) Math.Ceiling(this.interval); this.cookie = new object(); this.timer = new System.Threading.Timer(this.callback, this.cookie, dueTime, this.autoReset ? dueTime : -1); } else this.UpdateTimer(); }不过 System.Threading.Timer的属性和方法都更加友善,我通常在使用中不设计更新界面,都会使用这个定时器类,有一点要说明的是,将SynchronizingObject属性赋值到控件后,事件中代码会在控件上委托调用,如timer.SynchronizingObject = this;可以看下System.Timers.Timer内部是如何实现的。if (elapsedEventHandler != null) { if (this.SynchronizingObject != null && this.SynchronizingObject.InvokeRequired) { this.SynchronizingObject.BeginInvoke(elapsedEventHandler, new object[] { this, elapsedEventArgs }); } else { elapsedEventHandler(this, elapsedEventArgs); } } 虽然System.Timers.Timer定时器理论上是不受单线程限制,可以短时间内触发多次,但是实际上会受到线程池的限制,先看巨硬对于此的说明:如果 nullSynchronizingObject 属性,则在 ThreadPool 线程上引发 Elapsed 事件。 如果 Elapsed 事件的处理持续时间超过 Interval,则可能会在其他 ThreadPool 线程上再次引发该事件。 在这种情况下,事件处理程序应该是可重入的。1、当SynchronizingObject不为null,将在指定的对象线程上触发事件,为单线程触发,与System.Windows.Forms.Timer执行方式相同;2、当SynchronizingObject不为null时将在线程池(ThreadPool)上引发事件,执行事件内的代码。理论上可以重复载入,但是会受到ThreadPool线程数限制,比如ThreadPool.SetMaxThreads(8, 8),那么定时器触发事件只能同时载入8次;4、后记我现在用定时器基本上都是用System.Timers.Timer,在我看来System.Timers.Timer可以用SynchronizingObject属性实现在主线程运行,也可以不设置SynchronizingObject属性,是事件在线程池里触发,作为后台线程使用,基本能满足我在开发中的使用需求。参考资料System.Timers NamespaceSystem.Windows.FormsSystem.Threading.ThreadPool Class
2020年07月13日
1,314 阅读
2 评论
0 点赞
2020-06-23
[经验栈]C#与是德科技信号发生器(Keysight RF Signal Generators)N9310A通信操作
[TOC]1、前言这次使用的仪器是是德科技(keysight)的射频信号发生器,型号为N9310A,来一张正面照。2、C#代码2.1 参考C#与泰克示波器(Tektronix oscilloscope)通信操作中C#代码;2.2 可以用是德科技提供的通信代码;环境:IO 程序库套件项目-引用-添加-程序集-Keysight.Visausing System; using Ivi.Visa; using Keysight.Visa; namespace IdnSample { class IdnSample { static void Main(string[] args) { GpibSession session = new GpibSession ("MyInstr", Ivi.Visa.AccessModes.None, 2000); try { IMessageBasedFormattedIO io = session.FormattedIO; io.PrintfAndFlush("*IDN?");//发送查询设备指令 string[] response = new string[] { "", "", "", "" }; io.Scanf("%,s", out response);//读取信息,以逗号或空格划分字符串 Console.WriteLine("Manufacturer: {0}", response[0]); Console.WriteLine("Instrument Model: {0}", response[1].TrimEnd(new char[] {'\n'})); if (response.Length > 2) { Console.WriteLine("Firmware Revision: {0}", response[2].TrimEnd(new char[] {'\n'})); } if (response.Length > 3) { Console.WriteLine("Serial Number: {0}", response[3].TrimEnd(new char[] {'\n'})); } } catch { Console.WriteLine("*IDN? query failed"); } finally { ession.Dispose(); session = null; } Console.WriteLine("Press any key to end..."); Console.ReadKey(); } } }2.3 使用Ivi.Visa.Interop类;using System; using Ivi.Visa.Interop; namespace HardwareAutomation { public class IviVisaInteropInstrumentsAPIs { FormattedIO488 instrument = new FormattedIO488(); ResourceManager rm = new ResourceManager(); public void Set(string usbAddress, int timeOut) { instrument.IO = (IMessage)rm.Open(usbAddress, AccessMode.NO_LOCK, 0, ""); instrument.IO.TerminationCharacterEnabled = true; instrument.IO.Timeout = timeOut; } public void Write(string WriteStr) { instrument.WriteString(WriteStr, true); } public string Read() { try { return instrument.ReadString(); } catch (Exception e) { //Console.WriteLine(e); //throw; return ""; } } } }3、简单指令:SYSTem:DATE? //查询日期,用于确认信号发生器是否连接正常 :FREQuency:CW 5 MHz //设置频率为5MHz :FREQuency:CW? //查询频率 :AMPLitude:CW 5 dBm //设置幅度为5dbm :RFOutput:STATe ON //打开射频输出 :AM:STATe ON //打开调幅模式 :AM:DEPTh 5 //设置调幅深度 :AM:SOURce EXT //设置调幅源为外部 :MOD:STATe ON //使能设置 :FM:STATe ON //打开调频模式 :FM:DEViation 5 KHz //设置调频偏差为5KHz :FM:SOURce EXT //设置调频源为外部 :MOD:STATe ON //使能设置 :PULM:STATe ON //打开脉冲模式 :PULM:SOURce EXT //设置脉冲源为外部 :MOD:STATe ON //使能设置参考资料N9310A User's GuideKeysight VISA.NET Help(C:\Program Files\ (x86)\Keysight\IO Libraries Suite\VisaNet.chm)
2020年06月23日
2,523 阅读
4 评论
0 点赞
2020-06-22
[经验栈]C#与泰克示波器(Tektronix oscilloscope)MSO64通信操作
1、前言此次需要用到工具操作示波器动态配置和检验数据,下面为此次开发的一些总结记录。按理说这里应该用泰克(tektronix)提供的示波器(oscilloscope)驱动和API,但是我没有找到泰克提供的.NET版本的API,我又不是特别熟悉C封装到C#的开发,所以干脆使用了NI-VISA .NET,可能是没有使用到特殊驱动部分,使用并没有出现异常。2、安装环境1、NI-VISA3、C#代码using System; using System.Collections.Generic; using Ivi.Visa; using NationalInstruments.Visa; namespace VisaInstruments { public class NiVisaInstrumentsAPIs { private MessageBasedSession mbSession; private IVisaAsyncResult asyncHandle = null; public void FindResources(string filter) { using (var rm = new ResourceManager()) { try { IEnumerable<string> resources = rm.Find(filter); foreach (string s in resources) { //可以根据ParseResult查询出硬件类型,如Custom,Gpib,Serial,Usb等 //ParseResult parseResult = rm.Parse(s); //HardwareInterfaceType hardwareType = parseResult.InterfaceType; } } catch (Exception ex) { //处理错误 } } } public bool OpenInstrument(string address) { try { using (var rmSession = new ResourceManager()) { mbSession = (MessageBasedSession)rmSession.Open(address); //mbSession.SynchronizeCallbacks = true;使用异步方法需设SynchronizeCallbacks为true return true; } } catch (Exception exp) { return false; } } public void Write(string s) { mbSession.RawIO.Write(ReplaceCommonEscapeSequences(s)); } public string Read() { return InsertCommonEscapeSequences(mbSession.RawIO.ReadString()); } public void WriteAsync(string s) { try { string textToWrite = ReplaceCommonEscapeSequences(s); asyncHandle = mbSession.RawIO.BeginWrite( textToWrite, new VisaAsyncCallback(OnWriteComplete), (object)textToWrite.Length); } catch (Exception exp) { } } private void OnWriteComplete(IVisaAsyncResult result) { try { mbSession.RawIO.EndWrite(result); // "Success"; } catch (Exception exp) { } } public void ReadAsync() { try { asyncHandle = mbSession.RawIO.BeginRead( 1024, new VisaAsyncCallback(OnReadComplete), null); } catch (Exception exp) { } } private void OnReadComplete(IVisaAsyncResult result) { try { string responseString = mbSession.RawIO.EndReadString(result); string info = InsertCommonEscapeSequences(responseString); } catch (Exception exp) { } } public void AbortRW() { try { mbSession.RawIO.AbortAsyncOperation(asyncHandle); } catch (Exception exp) { } } private string ReplaceCommonEscapeSequences(string s) { return (s != null) ? s.Replace("\\n", "\n").Replace("\\r", "\r") : s; } private string InsertCommonEscapeSequences(string s) { return (s != null) ? s.Replace("\n", "\\n").Replace("\r", "\\r") : s; } } }4、实体按钮对应指令重新设置参数 --- *RST 前面板Autoset按钮 ---- AUTOSet EXECute 前面板通道1,2,3,4按钮 --- DISplay:GLObal:CH1:STATE on ACQUIRE:STOPAFTER RUNSTOP 前面板Single/Seq按钮 --- ACQUIRE:STOPAFTER SEQuence 前面板放大镜按钮 --- DISplay:WAVEView1:ZOOM:ZOOM1:STATe ON 前面板Default setup按钮 --- FACtory 需要先执行此条命令解锁命令操作旋钮 HORIZONTAL:DELAY:MODE ON 前面板HORizontal区域position旋钮 -- HORizontal:DELay:TIME 0.3 前面板HORizontal区域scale旋钮 HORIZONTAL:MODE:SCALE 0.5e-3 HORIZONTAL:MODE:SCALE? 前面板vertical区域scale旋钮 CH1:SCAle 100E-2 前面板vertical区域position旋钮 CH2:POSition -2.0 前面板touch off按钮 --- TOUCHSCReen:STATe OFF 前面板trigger区域force按钮 --- TRIGGER FORCE 前面板trigger区域mode按钮 --- TRIGger:A:MODe {AUTO|NORMal} 前面板A,B旋钮 --- TRIGger:{A|B|B:RESET}5、简单测量参数指令//设定读取通道和参数 MEASUREMENT:MEAS1:TYPE AMPLITUDE MEASUREMENT:MEAS1:SOURCE CH1 //读取信息 MEASUREMENT:MEAS1:RESUlts:CURRentacq:MEAN? //删除测试信息 MEASUREMENT:DELETE "MEAS1" //截屏 SAVE:IMAGE "C:/Dut12–tests.png" //可测参数列表 MEASUrement:MEAS<x>:TYPe {ACCOMMONMODE|ACRMS|AMPlITUDE|AREA|BASE|BITAMPLITUDE|BITHIGH|BITLOW|BURSTWIDTH|COMMONMODE|DATARATE|DCD|DDJ|DDRAOS|DDRAOSPERTCK|DDRAOSPERUI|DDRAUS|DDRAUSPERTCK|DDRAUSPERUI|DDRHOLDDIFF|DDRSETUPDIFF|DDRTCHABS|DDRTCHAVERAGE|DDRTCKAVERAGE|DDRTCLABS|DDRTCLAVERAGE|DDRTERRMN|DDRTERRN|DDRTJITCC|DDRTJITDUTY|DDRTJITPER|DDRTPST|DDRTRPRE|DDRTWPRE|DDRVIXAC|DDRTDQSCK|DELAY|DJ|DJDIRAC|DPMOVERSHOOT|DPMUNDERSHOOT|DPMRIPPLE|DPMTURNOFFTIME|DPMTURNONTIME|EYEHIGH|EYELOW|FALLSLEWRATE|FAHIGH|HEIGHT|HEIGHTBER|HIGHTIME|HOLD|JITTERSUMMARY|J2|J9|LOW|LOWTIME|MAXIMUM|MEAN|MINIMUM|NDUtY|NPERIOD|NPJ|NOVERSHOOT|NWIDTH|PDUTTY|PERIOD|PHASE|PHASENOISE|PJ|PK2Pk|POVERSHOOT|PWIDTH|QFACTOR|RISESLEWRATE|RISETIME|RJ|RJDIRAC|RMS|SRJ|SSCFREQDEV|SSCMODRATE|SETUP|SKEW|TIE|TIMEOUTSIDELEVEL|TJBER|TNTRATIO|TOP|UNITINTERVAL|VDIFFXOVR|WIDTH|WIDTHBER|}6、简单的GPIO测试用例//设置垂直刻度为300mv CH1:SCAle 300E-3 //位置为-3div CH1:POSition -3.0 //耦合为DC CH1:COUPLING DC //设置水平刻度为20ms HORIZONTAL:MODE:SCALE 20e-3 //打开采集 ACQUIRE:STATE ON //测量最大电压 MEASUREMENT:MEAS1:TYPE MAXIMUM MEASUREMENT:MEAS1:SOURCE CH1 //测量最小电压 MEASUREMENT:MEAS2:TYPE MINIMUM MEASUREMENT:MEAS2:SOURCE CH1 //测量高值 MEASUREMENT:MEAS3:TYPE TOP MEASUREMENT:MEAS3:SOURCE CH1 //测量低值 MEASUREMENT:MEAS4:TYPE BASE MEASUREMENT:MEAS4:SOURCE CH1 //停止采集 ACQUIRE:STATE OFF //设置标签 CH1:LABEL:NAME "GPIO1HIGH" //截屏 SAVE:IMAGE "G:/GPIO1HIGH.png"参考资料4, 5, 6 Series MSO (MSO44, MSO46, MSO54, MSO56, MSO58, MSO58LP, MSO64, LPD64) Programmer ManualTEKVISA Connectivity Software - V4.2.0
2020年06月22日
1,700 阅读
2 评论
0 点赞
2020-06-18
[经验栈]C#监测IPv4v6网速及流量
1、前言 最近做项目需要用到监测网速及流量,我经过百度和墙内谷歌都没能快速发现监测IPV6流量和网速的用例;也经过自己的一番查询和调试,浪费了不少时间,现在作为经验分享出来希望大家指正。2、C#代码using System.Net.NetworkInformation; using System.Timers; namespace Monitor { public class MonitorNetwork { public string UpSpeed { get; set; } public string DownSpeed { get; set; } public string AllTraffic { get; set; } private string NetCardDescription { get; set; } //建立连接时上传的数据量 private long BaseTraffic { get; set; } private long OldUp { get; set; } private long OldDown { get; set; } private NetworkInterface networkInterface { get; set; } private Timer timer = new Timer() { Interval = 1000 }; public void Close() { timer.Stop(); } public MonitorNetwork(string netCardDescription) { timer.Elapsed += Timer_Elapsed; NetCardDescription = netCardDescription; timer.Interval = 1000; } public bool Start() { networkInterface = null; NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); foreach (var var in nics) { if (var.Description.Contains(NetCardDescription)) { networkInterface = var; break; } } if (networkInterface == null) { return false; } else { BaseTraffic = (networkInterface.GetIPStatistics().BytesSent + networkInterface.GetIPStatistics().BytesReceived); OldUp = networkInterface.GetIPStatistics().BytesSent; OldDown = networkInterface.GetIPStatistics().BytesReceived; timer.Start(); return true; } } private string[] units = new string[] {"KB/s","MB/s","GB/s" }; private void CalcUpSpeed() { long nowValue = networkInterface.GetIPStatistics().BytesSent; int num = 0; double value = (nowValue - OldUp) / 1024.0; while (value > 1023) { value = (value / 1024.0); num++; } UpSpeed = value.ToString("0.0") + units[num]; OldUp = nowValue; } private void CalcDownSpeed() { long nowValue = networkInterface.GetIPStatistics().BytesReceived; int num = 0; double value = (nowValue - OldDown) / 1024.0; while (value > 1023) { value = (value / 1024.0); num++; } DownSpeed = value.ToString("0.0") + units[num]; OldDown = nowValue; } private string[] unitAlls = new string[] { "KB", "MB", "GB" ,"TB"}; private void CalcAllTraffic() { long nowValue = OldDown+OldUp; int num = 0; double value = (nowValue- BaseTraffic) / 1024.0; while (value > 1023) { value = (value / 1024.0); num++; } AllTraffic = value.ToString("0.0") + unitAlls[num]; } private void Timer_Elapsed(object sender, ElapsedEventArgs e) { CalcUpSpeed(); CalcDownSpeed(); CalcAllTraffic(); } } } 3、胡说八道 虽然没能直接快速地百度到方法,但是实现这个需求的时候,心里是有个谱,Windows系统能监测到这个网速和流量,没理由实现不了,只需要一个方法将这个信息读取出来就好。最后实现这个需求是利用了System.Net.NetworkInformation这个程序集,但是这个程序集没有只接提供网速监测的方法,而是提供了接收和发送数据量的属性,需要自己计算出即使网速,所以这个网速不是特别的准确。 这个程序集其实一开始就看到了,前辈方法中使用的是IPv4InterfaceStatistics类中的BytesReceived属性和BytesSent属性实现的,但是在这个程序集里没有对应的IPv6类,恍恍惚惚。 然后呢,我就下意识以为这个程序集比较老旧,不支持IPv6统计信息读取,然后也是各种搜索无果,之后呢不死心想再来研究研究,东点点西瞅瞅,然后在NetworkInterface 类中发现了一个GetIPStatistics()方法,它的描述是“获取此 NetworkInterface 实例的 IP 统计信息。”。 然后就顺理成章的事了,根据GetIPStatistics()返回的IPInterfaceStatistics实例中的BytesReceived属性和BytesSent属性就能获取到收发的数据总量,然后根据这个信息就能计算出大约的网速。 经测试,利用IPInterfaceStatistics实例是能读取到IPv4和IPv6的总数据量的,因为这次的需求就是监测总量,如果需要单独监测IPv6的可以用总量减去IPv4部分。4、后记 老师以前喊我认真念书,我心想有百度还不够吗,再念能有百度聪明,有百度懂得多,后来渐渐明白,百度懂得多都是前辈的搬砖添瓦来的,共勉。参考资料 System.Net.NetworkInformation 命名空间
2020年06月18日
2,327 阅读
2 评论
0 点赞
1
2