C#静态函数正在向函数发送错误的参数


由于某种原因,我的代码向函数传递了错误的参数。

我有一个static类,比如说A类,它有这个函数AddMaster:

public static void AddMaster(string ipAddress, int port, List<RegisterMap> registers)
{
// THIS LINE PRINTS THE ACTUAL VALUES SENT FROM THE CALLER FUNCTION
System.IO.File.AppendAllText("datalog_MB.txt", ipAddress + "   " + registers[0].FriendlyName + "n");

new Thread(() =>
{
_tasks.Add(Task.Factory.StartNew(() =>
{
Monitor.Enter(_masters);
_masters.Add(new Master().Connect(ipAddress, port).SetRegisters(registers));
_masters.Last().OnEvent += MasterEvent;
Debug.WriteLine(_masters.Count + " TCP masters connected");
Monitor.Exit(_masters);
}));
}).Start();
}

我有另一个non-staticMaster,具有函数SetRegisters:

public Master SetRegisters(List<RegisterMap> registerList)
{
// HERE THE FriendlyName ALWAYS PRINTS THE VALUE OF THE LAST FUNCTION CALL
System.IO.File.AppendAllText("datalog_MB_1.txt", _hostname + "   " + registerList[0].FriendlyName + "n");
_registersToRead = registerList;
return this;
}

函数AddMaster()在循环中被调用。

第一个代码记录以下内容,这是正确的:

# datalog_MB.txt
192.168.0.12   192.168.0.12:Value 1
192.168.0.11   192.168.0.11:Value 1

但是,第二个代码块打印以下内容(请参阅第二个值已更改):

# datalog_MB_1.txt
192.168.0.12   192.168.0.11:Value 1
192.168.0.11   192.168.0.11:Value 1

编辑#1

foreach (var equipment in MSSQL.GetEquipments(true)) 
{
registers.Clear();

System.IO.File.AppendAllText("dataeq.txt", equipment.IPAddress + "    " + equipment.Name + "     " + equipment.ID +  "n");

try
{
registers.Add(
new RegisterMap
{
FriendlyName = equipment.IPAddress + ":Value 1",
Register = 2001,
Type = RegisterType.HoldingRegister,
StationID = 1
});

registers.Add(
new RegisterMap
{
FriendlyName = equipment.IPAddress + ":Value 2",
Register = 2002,
Type = RegisterType.HoldingRegister,
StationID = 1
});
A.AddMaster(equipment.IPAddress, 502, registers);
var json = new JavaScriptSerializer().Serialize(registers);

System.IO.File.AppendAllText("data_reg.txt", json + "nn");
}
catch(Exception err)
{
System.Windows.MessageBox.Show(err.Message);
}
}

编辑#2*

Fiddle:https://dotnetfiddle.net/h3yn7p

知道可能出了什么问题吗?

您不应该Clearregisters-重新创建它:

List<RegisterMap> registers = null;
foreach(var equipment in equipments) 
{
registers = new List<RegisterMap>(); 
....
}

否则,您将在多个线程中并行处理List<RegisterMap>的同一实例,同时对其进行操作(即,具有foreach(var equipment in equipments)循环的线程将运行并创建所有线程并启动它们),这可能会导致许多不同的并发问题。

还有一些注意事项:

  1. 考虑使用并发集合,例如ConcurrentBag<T>而不是Monitor+List(因为在当前代码中,它使Thread/Task处理毫无意义)
  2. 根据提供的代码,不需要创建Thread——任务就足够了。在现代.NET中,很少有需要手动创建Thread的情况,大多数时候都非常不鼓励(阅读更多)

相关内容

最新更新