C# 为什么Lock语句不';I don’我没有按预期工作

C# 为什么Lock语句不';I don’我没有按预期工作,c#,synchronization,locking,C#,Synchronization,Locking,我知道你期望这些threasd以并行方式运行,但它们是按顺序执行的。你的期望是正确的 然而,我不认为这和锁有任何关系。锁定只会防止读和写同时发生,而不会产生这种行为。在没有锁的情况下尝试验证。(但是,由于JiT编译器、CPU缓存失效和优化等原因,如果存在锁,即使没有直接影响,结果也可能不同) 我的最佳选择是读取线程非常慢,在写入完成所有操作之前不会完成一次。编写UI是很昂贵的,即使是在控制台这样的小事上。甚至特别是在那里。我使用robocopy备份了很多用户配置文件。如果它碰到很多非常小的文件,

我知道你期望这些threasd以并行方式运行,但它们是按顺序执行的。你的期望是正确的


然而,我不认为这和锁有任何关系。锁定只会防止读和写同时发生,而不会产生这种行为。在没有锁的情况下尝试验证。(但是,由于JiT编译器、CPU缓存失效和优化等原因,如果存在锁,即使没有直接影响,结果也可能不同)

我的最佳选择是读取线程非常慢,在写入完成所有操作之前不会完成一次。编写UI是很昂贵的,即使是在控制台这样的小事上。甚至特别是在那里。我使用robocopy备份了很多用户配置文件。如果它碰到很多非常小的文件,仅仅编写控制台就成为了实际的程序瓶颈,甚至超过了磁盘访问。而阻碍磁盘访问的瓶颈并不是经常发生的事情

如果您只为每个用户triggerd事件编写一次UI,您将不会注意到成本。但是从任何形式的循环中执行它——特别是在另一个线程中运行的循环——您将开始注意到它。我被特别告知,foreach的启动速度显然是for循环的一半

我甚至为此举了一个例子,尽管是在Windows窗体环境中:

Added value: 1
Collection state: 1
Added value: 15
Collection state: 1 15
Added value: 4
Collection state: 1 15 4
使用系统;
使用System.Windows.Forms;
命名空间UIWriteOverhead
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
int[]getNumbers(int上限)
{
int[]ReturnValue=新int[上限];
for(int i=0;i

但即使是这样的开销也很难有一个预先存在的结果。在某些时候,读取线程应该首先获得锁,阻止写入。但仍然有太多的变数无法确定。你应该尝试一个更简单的例子,用更一致的(并且更少的)写作。在控制台上写“A”和“B”,而不是像这样复杂的东西怎么样?

将结果作为文本添加到问题中。也要准确地预测预期结果,我看这里没有什么大问题。把10换成更大的。我不认为这和锁有任何关系。锁定只会防止读和写同时发生。不带锁试试看。我最好的办法是,出于某种原因,这些线程是按顺序执行的。一个特别的问题是,写入UI的成本很高。在正常操作中,您不会注意到。但是,像Robocopy这样的软件在一长串短文件中快速循环,实际上更新控制台的时间成了瓶颈。@TheodorZoulias-这些数字足够随机。Stepan结果有什么问题?你能举一个你期望看到的结果的例子吗?@将军:正如不屈不挠的虫子兔子所说,“这是一种生活”。)
Added value: 1
Collection state: 1
Added value: 15
Collection state: 1 15
Added value: 4
Collection state: 1 15 4
using System;
using System.Windows.Forms;

namespace UIWriteOverhead
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        int[] getNumbers(int upperLimit)
        {
            int[] ReturnValue = new int[upperLimit];

            for (int i = 0; i < ReturnValue.Length; i++)
                ReturnValue[i] = i;

            return ReturnValue;
        }

        void printWithBuffer(int[] Values)
        {
            textBox1.Text = "";
            string buffer = "";

            foreach (int Number in Values)
                buffer += Number.ToString() + Environment.NewLine;
            textBox1.Text = buffer;
        }

        void printDirectly(int[] Values){
            textBox1.Text = "";

            foreach (int Number in Values)
                textBox1.Text += Number.ToString() + Environment.NewLine;
        }

        private void btnPrintBuffer_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Generating Numbers");
            int[] temp = getNumbers(10000);
            MessageBox.Show("Printing with buffer");
            printWithBuffer(temp);
            MessageBox.Show("Printing done");
        }

        private void btnPrintDirect_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Generating Numbers");
            int[] temp = getNumbers(1000);
            MessageBox.Show("Printing directly");
            printDirectly(temp);
            MessageBox.Show("Printing done");
        }
    }
}