现在,我们将此示例重构。将实际的工作代码移到一个类型SampleClass中,该示例要在多个SampleClass实例间操作一个静态字段,如下所示:
- private void buttonStartThreads_Click(object sender, EventArgs e)
- {
- SampleClass sample1 = new SampleClass();
- SampleClass sample2 = new SampleClass();
- sample1.StartT1();
- sample2.StartT2();
- }
-
- class SampleClass
- {
- public static List<string> TempList = new List<string>() { "init0",
- "init1", "init2" };
- static AutoResetEvent autoSet = new AutoResetEvent(false);
- object syncObj = new object();
-
- public void StartT1()
- {
- Thread t1 = new Thread(() =>
- {
- //确保等待t2开始之后才运行下面的代码
- autoSet.WaitOne();
- lock (syncObj)
- {
- foreach (var item in TempList)
- {
- Thread.Sleep(1000);
- }
- }
- });
- t1.IsBackground = true;
- t1.Start();
- }
-
- public void StartT2()
- {
- Thread t2 = new Thread(() =>
- {
- //通知t1可以执行代码
- autoSet.Set();
- //沉睡1秒是为了确保删除操作在t1的迭代过程中
- Thread.Sleep(1000);
- lock (syncObj)
- {
- TempList.RemoveAt(1);
- }
- });
- t2.IsBackground = true;
- t2.Start();
- }
- }
|
该示例运行起来会抛出异常InvalidOperationException:
“集合已修改;可能无法执行枚举。”
查看类型SampleClass的方法StartT1和StartT2,方法内部锁定的是SampleClass的实例变量syncObject。实例变量意味着,每创建一个SampleClass的实例都会生成一个syncObject对象。在本例中,调用者一共创建了两个SampleClass实例,继而分别调用:
- sample1.StartT1();
- sample2.StartT2();
|