Я понимаю, что вы ожидали, что эти три будут работать в параллельном режиме, но вместо этого они выполняются последовательно. Вы ожидаете, что это правильно.
Я не думаю, что это как-то связано с блокировкой. Блокировка только предотвратит одновременное чтение и запись, но не приведет к такому поведению. Попробуйте без блокировки, чтобы проверить. (Однако из-за таких вещей, как JiT-компилятор, аннулирование кэша ЦП и оптимизация, результаты могут все еще отличаться, если есть блокировка, даже если она не оказывает прямого влияния).
Лучше всего, чтобы поток чтения былпросто так медленно, он не заканчивает один раз , пока запись не пройдет через все его указания. Написание пользовательского интерфейса стоит дорого, даже на чем-то тривиальном, как консоль. Или даже особенно там. Я делаю много резервных копий пользовательских профилей, используя robocopy. И если он попадает во множество очень маленьких файлов, простое написание Консоли становится узким местом актуальной программы , когда-либо превышающим доступ к диску . И что-то из-за узкого доступа к диску - это не то, что случается часто.
Если вы пишете пользовательский интерфейс только один раз для события, инициируемого пользователем, вы не заметите стоимость. Но сделайте это из любой формы цикла - особенно из цикла в другом потоке - и вы начнете замечать это. В частности, мне сообщили, что foreach, по-видимому, вдвое медленнее при запуске, чем цикл for.
Я даже сделал пример для этого, хотя и в среде Windows Forms:
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");
}
}
}
Нодаже такие накладные расходы довольно неприятно иметь постоянный результат. Через некоторое время поток чтения должен сначала получить блокировку, блокирующую запись. Но все же, есть слишком много переменных, чтобы сказать наверняка. Вероятно, вы должны попробовать более простой пример, с более последовательной (и намного меньшей) перепиской. А как насчет записи «A» и «B» на консоль вместо сложных вещей вроде этого?