System.Timers.Timer抛出异常

时间:2017-08-21 05:29:41

标签: c# timer threadpool eventhandler

我正在使用List<>实现代码。每个列表都有一个Class Type项。此类的一个成员是名为“TimeOut”的System.Timer.Timer变量。 TimeOut.Interval值为10,每个TimeOut.Interval(10)都应触发TimeOut.Elapsed事件。

事件是从列表中删除该项目。事件重载,以便

TimeOut.Elapsed += (sender, e) => DeleteEntry(sender, e, i)

其中i是列表中项目的索引。

对于Event方法,

public void DeleteEntry(object sender, System.Timers.ElapsedEventArgs e, int i)
{
    //Delete Item from List
    listTable.RemoveAt(i);
}

我的问题是,如果两个项目一起启动计时器并决定在相同的指定时间间隔之后调用EventHandler,则首先添加到列表中的那个被删除,然后当第二个项目立即被调用时,它会抛出错误告诉我索引超出范围。发生这种情况是因为删除了其中一个项目,列表将其索引向上移动,并且发送到DeleteEntry方法的“i”是不再存在的旧项目。

在其他情况下,如果列表中有两个以上的项目,则删除错误的项目,因为该方法使用了错误的索引。

使用数组不是我的选择。每次删除元素时都要对数组进行解组来做太多工作。

我该如何解决这个问题?我是否需要使用ThreadPool做一些事情,设置一个标志或类似的东西?无论如何,SynchronizingObject属性可以帮助吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

解决方案:

从您的说法看,您的问题似乎是列表转移,您不知道该项目在什么时候。如果是这种情况,您将需要访问列表的Count属性,该属性告诉您列表中的项目数量。小心使用它,因为它不考虑索引为0.

解决方案:

从您的说法看,您的问题似乎是列表转移,您不知道该项目在什么时候。如果是这种情况,您将需要访问列表的Count属性,该属性告诉您列表中的项目数量。小心使用它,因为它不考虑索引为0.

编辑:

示例:

    private static List<int> Numbers = new List<int>();
    private static readonly object NumbersLock = new object();
    static void Main(string[] args)
    {
        Thread X = new Thread(() => {
            AddNumbers();
        });

        Thread Y = new Thread(() => {
            AddNumbers();
        });

        X.Start();
        Y.Start();
    }

    private static void AddNumbers() {
        Random r = new Random(DateTime.UtcNow.Millisecond);

        while (true) {
            lock (NumbersLock) {
                Numbers.Add(r.Next(0, 100));
            }
        }
    }