在Timer Tick事件中使用'lock'是死锁吗?

时间:2014-03-02 18:09:05

标签: c# winforms timer locking deadlock

我想知道这种方法是否有可能陷入僵局。

示例代码:单击应用程序按钮时,会创建一个Job对象并将其添加到作业列表中。添加代码受“锁定”保护。然后在计时器刻度事件中,我想从列表中删除已完成的作业 - 在计时器事件中锁定列表。

所以问题是,如果用户按下Add Job按钮,当timer事件锁定正在使用时,这个app会死锁吗?

Timer是一个Windows窗体计时器。

public partial class Form1 : Form
{
    object listLock = new object();
    List<Job> jobsList = new List<Job>();
    public Form1()
    {
        InitializeComponent();
        timer1.Start();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        Job aJob;
        lock(listLock)
        {
            for (int i = jobsList.Count - 1; i > -1; i--)
            {
                aJob = jobsList[i];
                if (aJob.IsCompleted)
                {
                    jobsList.RemoveAt(i);
                }

            }
        }

    }

    private void button1_Click(object sender, EventArgs e)
    {
        lock (listLock)
        {
            Job aJob = new Job();
            jobsList.Add(aJob);
        }

    }
}

//=====================================
  class Job
    {
        bool isCompleted = false;

        public bool IsCompleted
        {
            get { return isCompleted; }
            set { isCompleted = value; }
        }

        public Job()
        {
            // do some work then mark complete
            IsCompleted = true;
        }
}

1 个答案:

答案 0 :(得分:2)

从主消息循环调度定时器事件(来自Windows窗体定时器)。因此,它们永远不会与任何其他UI事件的处理程序重叠。

按下按钮将进入消息队列,并在定时器Tick处理程序完成后进行处理。 (因此,您不需要锁定仅由UI事件处理程序操纵的数据结构,因为它们将按照排队的顺序依次运行)