Skip to main content
 首页 » 编程设计

c#之锁定的 console.writeline 调用工作不正常

2024年01月25日29TianFang

尝试从锁定部分调用 Console.WriteLine,但似乎无法正常工作 - 控制台未锁定。下面是简单应用程序的代码 - 两个线程并行填充一个列表,出于调试目的,我正在打印有关线程工作和新添加元素的信息。

using System; 
using System.Threading; 
using System.Collections.Generic; 
 
class ThreadSafe 
{ 
    static object SyncRoot = new object(); 
 
    static int threadsCount = 0; 
    static List<string> list = new List<string>(); 
 
    static void Main() 
    { 
        Thread t1 = new Thread(AddItems); 
        Thread t2 = new Thread(AddItems); 
        t1.Start(); 
        t2.Start(); 
 
        t1.Join(); 
        t2.Join(); 
 
        PrintItems(); 
 
        Console.ReadLine(); 
    } 
 
    static void PrintItems() 
    { 
        string[] items; 
 
        Console.WriteLine("Converting list to array..."); 
        items = list.ToArray(); 
 
        Console.WriteLine("Printing array..."); 
        foreach (string s in items) 
            Console.WriteLine(s); 
    } 
 
    static void AddItems() 
    { 
        int threadNo = threadsCount; 
        threadsCount++; 
 
 
        { 
            Console.WriteLine("Populating list from {0} item in thread N {1}...", list.Count, threadNo); 
            for (int i = 0; i < 50; i++) 
            { 
                lock (SyncRoot) 
                { 
                    Console.Write("Population. Thread N {0} is running. ", threadNo); 
                    Console.WriteLine("Element N {0} has been added successfully.", list.Count); 
                    list.Add("Item " + list.Count); 
                } 
            } 
        } 
    } 
} 

结果:

Populating list from 0 item in thread N 1... 
Population. Thread N 1 is running. Element N 0 has been added successfully. 
Population. Thread N 1 is running. Element N 1 has been added successfully. 
Population. Thread N 1 is running. Element N 2 has been added successfully. 
Population. Thread N 1 is running. Element N 3 has been added successfully. 
Population. Thread N 1 is running. Element N 4 has been added successfully. 
Population. Thread N 1 is running. Element N 5 has been added successfully. 
Population. Thread N 1 is running. Element N 6 has been added successfully. 
Population. Thread N 1 is running. Element N 7 has been added successfully. 
Population. Thread N 1 is running. Element N 8 has been added successfully. 
Population. Thread N 1 is running. Element N 9 has been added successfully. 
Population. Thread N 1 is running. Element N 10 has been added successfully. 
Population. Thread N 1 is running. Element N 11 has been added successfully. 
Population. Thread N 1 is running. Element N 12 has been added successfully. 
Population. Thread N 1 is running. Element N 13 has been added successfully. 
Population. Thread N 1 is running. Element N 14 has been added successfully. 
Population. Thread N 1 is running. Element N 15 has been added successfully. 
Population. Thread N 1 is running. Populating list from 0 item in thread N 0... 
Element N 16 has been added successfully. 
Population. Thread N 0 is running. Element N 17 has been added successfully. 
Population. Thread N 0 is running. Element N 18 has been added successfully. 
Population. Thread N 0 is running. Element N 19 has been added successfully. 

在第 15 步和第 16 步之间,新的 first 以某种方式开始运行,并在锁定部分的 Console.Write 和 Console.WriteLine 调用之间输出其内容... Console.WriteLine 确实是非线程安全的吗?还是我做错了什么?

谢谢!

请您参考如下方法:

您有 2 个 AddItems 线程,每个线程都进行解锁输出(函数中的第一个)。这种交错是预期的行为。你需要:

  lock (SyncRoot) 
  { 
    Console.WriteLine("Populating list from {0} item in thread N {1}...", list.Count, threadNo);  
  }