由于工作中遇到了使用非静态变量时,异步线程的值未同步变更的情况,修改成静态变量后程式到达预期效果;故而找度娘了解了一下静态与非静态的区别。
以下四点从百度搬过来的:
一、C#静态成员: 静态成员属于类所有,非静态成员属于类的实例所有。
每创建一个类的实例,都会在内存中为非静态成员新分配一块存储;静态成员属于类所有,为各个类的实例所公用,无论类创建了多少实例,类的静态成员在内存中只占同一块区域。
⼆、C#静态⽅法C#静态⽅法属于类所有,类实例化前即可使⽤。
⾮静态⽅法可以访问类中的任何成员,静态⽅法只能访问类中的静态成员。因为静态⽅法在类实例化前就可以使⽤,⽽类中的⾮静态变量必须在实例化之后才能分配内存,这样,C#静态⽅法调⽤时⽆法判断⾮静态变量使⽤的内存地址。所以⽆法使⽤。⽽静态变量的地址对类来说是固定的,故可以使⽤。
三、C#静态⽅法是⼀种特殊的成员⽅法。
它不属于类的某⼀个具体的实例,⽽是属于类本⾝。所以对静态⽅法不需要⾸先创建⼀个类的实例,⽽是采⽤类名.静态⽅法的格式 。static内部只能出现static变量和其他static⽅法!⽽且static⽅法中还不能使⽤this....等关键字..因为它是属于整个类!静态⽅法效率上要⽐实例化⾼,静态⽅法的缺点是不⾃动进⾏销毁,⽽实例化的则可以做销毁。静态⽅法和静态变量创建后始终使⽤同⼀块内存,⽽使⽤实例的⽅式会创建多个内存。
四、C#静态⽅法中获取类的名称
静态⽅法中⽤:
string className = System.Reflection.MethodBase. GetCurrentMethod().ReflectedType.FullName;
⾮静态⽅法中还可以⽤:
string className = this.GetType().FullName;
使⽤静态得准则就是:1.保证不会产⽣并发。2. 在⽅便快捷和开发难度上做⼀个衡量
个人总结:静态类或变量,不需要实例化就能使用,固定的内存地址,适合我用来做公共变量作用
if (Program.AdditionalTask != null)
{
if (Program.AdditionalTask.Status == TaskStatus.Running)
{
dtAdditionalTaskStart = DateTime.Now;
return;
}//附加线程已在运行中,只延长一下超时时间,不重复开启
}
Program.AdditionalTask = Task.Run(() =>
{
dtAdditionalTaskStart = DateTime.Now;
double nowRedValue = 0;
double NowWeith = Program._nWeightNow / 10;
double startWeight = Program._nWeightNow / 10;//开始时的重量传感器的值
Thread.Sleep(5000);
Program.objCameraTool._logNet.WriteInfo($",{DateTime.Now.ToString("HH:mm:ss.fff")},颜色识别开始\n");//存设备运行日志
ColorRecognitionTool._时间And数据 = new Dictionary<string, List<double>>();//重置字典
ColorRecognitionTool._每秒数据平均值 = new List<double>();//重置时间平均值
while (true)
{
Thread.Sleep(20);//循环间隙
DateTime NowTime = DateTime.Now;//当前随时间
if ((NowTime - dtAdditionalTaskStart).TotalSeconds > 300)
{
lbFlowTitle.BeginInvoke(new Action(() => { lbFlowTitle.Text = "ColorReadTimeOut-300s"; }));
Program.objCameraTool._logNet.WriteInfo($",{DateTime.Now.ToString("HH:mm:ss.fff")},颜色识别超时\n超时:{NowTime}-{dtAdditionalTaskStart}={(NowTime - dtAdditionalTaskStart).TotalSeconds}");//存设备运行日志
break;
}//读取超时
//300s
if (Program._OperationStatus != Program.OperationStatus.Star)
{
Program.objCameraTool._logNet.WriteInfo($",{DateTime.Now.ToString("HH:mm:ss.fff")},颜色识别主程序停止\n");//存设备运行日志
break;
}//程序停止运行 自动退出
#region 方式1 重量变化+固定区间判断值差距
NowWeith = Program._nWeightNow / 10;
if ((NowWeith - startWeight) > 2)
{
if (!WeithRun)
{
Program.objCameraTool._logNet.WriteInfo($",{DateTime.Now.ToString("HH:mm:ss.fff")},——-称重条件满足,开始监测\n");//存设备运行日志
WeithRun = true;
}
double[] nowValue = Program.objCameraTool.ReadColor();
nowRedValue = nowValue[0];//读取画面颜色值 0-R,1-G,2-B,3-Gary
if ((NowTime - dtLast).TotalSeconds > 0.6)
{
lbl_ColorGary.BeginInvoke(new Action(() => { lbl_ColorGary.Text = $"R: {nowRedValue.ToString("0.#")}"; }));
dtLast = NowTime;
}//0.6s刷新一下界面显示值
bool result = ColorRecognitionTool._数据处理(nowRedValue, NowTime);
if (result)
{
byData = CommandClass.ReadColorOperation(CommandClass._1780, 2);//识别到 连续的 目标颜色
Program.m_tcpClient.Send(byData);
Program.m_tcpClient.Logger.Message($"已识别颜色 2-4下行数据:{CommandClass.ByteToHexStr(byData)}");
Program.objCameraTool._logNet.WriteInfo($",{DateTime.Now.ToString("HH:mm:ss.fff")},颜色识别4结束\n");//存设备运行日志
break;
}
}
#endregion 方式1 固定区间判断值差距
#region 方式2 当前数据与前5秒数据判断
if (false)
{
AddData(nowRedValue);
double changeValue = CompareCurrentWithPreviousFiveSeconds();
if (changeValue > 20)
{
x++;
}
if (x > 5)
{
byData = CommandClass.ReadColorOperation(CommandClass._1780, 2);//识别到 连续的 目标颜色
Program.m_tcpClient.Send(byData);
Program.m_tcpClient.Logger.Message($"已识别颜色 2-3下行数据:{CommandClass.ByteToHexStr(byData)}");
Program.objCameraTool._logNet.WriteInfo($",{DateTime.Now.ToString("HH:mm:ss.fff")},颜色识别结束\n");//存设备运行日志
break;
}
}
#endregion 方式2 当前数据与前5秒数据判断
#region 方式3 先判断重量变化, 再加入字典判断时间段的值变化
if (false)
{
NowWeith = Program._nWeightNow / 10;
if ((NowWeith - startWeight) > 3)
{
if (queueA.Count < 500)
{
queueA.Enqueue(nowRedValue);
}
else
{
if (_subCollections.Count == 0)
{
if (CalculateResult(queueA) != 10)
{
_subCollections.Add(queueA);
MeanValues.Add(Program.objCameraTool.GetAverage(queueA));//计算数组平均值
}
else
{
queueA.Dequeue();
queueA.Enqueue(nowRedValue);
}
}
else
{
queueB.Enqueue(nowRedValue);
}
if (queueB.Count > 50 && _subCollections.Count >= 1)
{
_subCollections.Add(queueB);//填满50个数据的值加入集合
MeanValues.Add(Program.objCameraTool.GetAverage(queueB));//计算数组平均值
queueB = new Queue<double>();//填入新的数据
}//数组数据足够打包
}
if (MeanValues.Count > 15)
{
if (MeanValues[MeanValues.Count - 1] - MeanValues[MeanValues.Count - 3] > 20 || MeanValues[MeanValues.Count - 1] - MeanValues[MeanValues.Count - 2] > 20)
{
Console.WriteLine($"{MeanValues[MeanValues.Count - 1]}-{MeanValues[MeanValues.Count - 2]}={MeanValues[MeanValues.Count - 1] - MeanValues[MeanValues.Count - 2]}");
byData = CommandClass.ReadColorOperation(CommandClass._1780, 2);//识别到 连续的 目标颜色
Program.m_tcpClient.Send(byData);
Program.m_tcpClient.Logger.Message($"已识别颜色 2-2下行数据:{CommandClass.ByteToHexStr(byData)}");
break;
}//平均值数据
}//平均值数据
DicAdd(nowRedValue, NowTime);
double CompareValue = 0;
int result = DicCompare(NowTime.Second, out CompareValue);
if (result == 1)
{
x++;
}//上升
else if (result == 2)
{
y++;
}//平稳
if (CompareValue > 40)
{
z++;
}//增大
if (x > 3 || z > 0)
{
byData = CommandClass.ReadColorOperation(CommandClass._1780, 2);//识别到 连续的 目标颜色
Program.m_tcpClient.Send(byData);
Program.m_tcpClient.Logger.Message($"已识别颜色 2-3下行数据:{CommandClass.ByteToHexStr(byData)}");
Program.objCameraTool._logNet.WriteInfo($",{DateTime.Now.ToString("HH:mm:ss.fff")},颜色识别结束\n");//存设备运行日志
break;
}//连续3秒数据变大 或者一秒平均变大超过40
}//重量变化大于3g 剔除前面缓冲液的干扰
}
#endregion
//if ((NowTime - dtLast).TotalSeconds > 0.8)
//{
// lbl_ColorGary.BeginInvoke(new Action(() => { lbl_ColorGary.Text = $"R: {nowRedValue.ToString("0.#")}"; }));
// dtLast = NowTime;
//}//0.8s刷新一下界面显示值
if (A1 >= 40 || A2 >= 40 || B1 > 40 || B2 > 40 || C1 > 40 || C2 > 40 || D1 > 40 || D2 > 40 || E1 > 40 || E2 > 40 || F1 > 40 || F2 > 40 || G1 > 40 || G2 > 40 || H1 > 40 || H2 > 40)
{
dtAdditionalTaskStart = NowTime;
}
}//循环
Program.objCameraTool.Stop();
}, Program.cts.Token);
带上一段个人写的笨比的颜色识别异步线程,淘宝淘的摄像头拿来识别血液颜色