Threadstart在定时器的循环中仅执行所述循环中的最后一个线程。

时间:2011-09-08 18:27:48

标签: c# multithreading loops

我有一个执行循环执行一系列线程的计时器。每个线程只轮询串行设备(在唯一端口上)并将数据写入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写入数据库的数据。

1 个答案:

答案 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();
 }