我有一个执行循环执行一系列线程的计时器。每个线程只轮询串行设备(在唯一端口上)并将数据写入MySQL数据库以供Web应用程序拾取。
我注意到循环中的最后一个线程正在执行。
这是我的计时器Interval
方法。
static void glob_timer_Elapsed(object sender, ElapsedEventArgs e)
{
foreach (object[] row in user_ids)
{
Console.WriteLine(row[0].ToString() + ":" + row[1].ToString());
ThreadStart starter = delegate { Functions.UpdateFor(row[0].ToString(), row[1].ToString()); };
new Thread(starter).Start();
}
}
user_ids是包含查询行的List<object[]>
;所以row[0]
= 用户ID ,row[1]
= Com端口名称
在函数UpdateFor()
中:
public static void UpdateFor(string uid, string com_name)
{
try
{
Console.WriteLine("[" + uid + "]- " + DateTime.Now.ToString() + " : " + "Begin read transmission.");
运行时,在控制台中我看到
1:COM1
2:COM2
[2]-{DateTime} : Begin read transmission
为什么我没有看到UpdateFor
的uid 1.
注意:我还验证了从未写入应该从COM1写入数据库的数据。
答案 0 :(得分:5)
你正在遭遇关闭问题。每个委托在每个循环中捕获对object[] row
的引用,迭代,因此它们都使用相同的引用执行,即无论行的最终值是什么。您需要简单地指定一个内部变量,以确保每个委托获得唯一的引用。
foreach (object[] row in user_ids)
{
var innerReference = row;
Console.WriteLine(innerReference[0].ToString() + ":" + innerReference[1].ToString());
ThreadStart starter = delegate { Functions.UpdateFor(innerReference[0].ToString(), innerReference[1].ToString()); };
new Thread(starter).Start();
}