C# 类中的static变量对实例的影响

背景:最近在做一个多串口通讯相关的功能,发现返回的数据错乱。再次做个笔记以防之后做项目的时候再遇到这种情况。

设计构想:串口通讯这块封装成一个类,接收到数据后,把数据压入解析类中的队列中,解析类解析完一个数据就通过事件委托的方式把数据传递给串口类;主界面上订阅了串口发送数据的事件,来接收串口类返回的数据。主界面中new两个实例,接收数据,但从返回的情况,发现返回的数据存在错乱,不正确的。主要的是不小心把解析类中存储的byte[]数组变量定义为static变量

下面就写一个简单的程序模拟程序。

调用的类对象

public class EventTest
{
	Object eventLock = new object();
	public event EventHandler DataEvent;
	public int result = 0;
	public static int count = 0;
	public EventTest(int type)
	{
		Task.Run(() =>
		{
			while (true)
			{
				lock (eventLock)
				{
					if (DataEvent != null)
					{
						count ++;
						DataEvent(this, count);
					}
					System.Threading.Thread.Sleep(1000 * 5);
				}
			}
		});
	}
}

主程序调用代码 

public partial class MainWindow : Window
{
	public MainWindow()
	{
		InitializeComponent();
	}

	EventTest eventTest1;
	EventTest eventTest2;
	private void Button_Click3(object sender, RoutedEventArgs e)
	{
		eventTest1 = new EventTest(5);
		eventTest1.DataEvent += EventTest1_DataEvent;
	}

	private void EventTest1_DataEvent(object sender, int e)
	{
		Console.WriteLine("接收到1" + "返回数据 " + e.ToString());
	}

	private void Button_Click4(object sender, RoutedEventArgs e)
	{

		eventTest2 = new EventTest(100);
		eventTest2.DataEvent += EventTest2_DataEvent;
	}

	private void EventTest2_DataEvent(object sender, int e)
	{
		Console.WriteLine("接收到2" + "返回数据 " + e.ToString());
	}
}

运行结果图如下,从截图可以看出,第二个按钮接收的返回并不是正确的,而是在第一个按钮count运算后再累加的结果。

C# 类中的static变量对实例的影响_第1张图片

当把 public static int count = 0;改写成 public int count = 0;时,即把count定义为动态变量,则结果就执行正常了。

C# 类中的static变量对实例的影响_第2张图片

下面就进行static变量相关的解析:

        这个问题其实很简单,没带static的变量属于对象,带了static的变量属于类本身,每一个类对只应一个class,在这个class被加载时,系统会在堆内存中为它分配一个空间,但每一个类可以创建出它的多个实例(也就是对象),当你在创建对像时系统会为你的每一个对像在堆内存中分配空间,这些对象都保存了对类中static的一个引用,也就是说不管你创建多少个对像,它们都指向同一个static变量,尽管类的实例包含该类的所有实例字段的单独副本,但每个static字段只有一个副本。所以就会出现数据错乱的情况。

        解决:把串口类以及串口类相关的解析类中的static变量全部改成动态变量后,就实现了多串口通讯的功能。

**************************************************************************************************************

你可能感兴趣的:(C#,#,C#,遇坑记,c#,C#,static)