Вы никогда не должны блокировать поток пользовательского интерфейса (с помощью сна или выполнения тяжелой работы), поскольку поток может обрабатывать только события пользовательского интерфейса (щелчки, повторное отображение, изменение размера) или запустить ваш код, а не оба. В случаях, когда вам необходимо выполнить какой-то долго выполняющийся код из обработчика событий, вы можете либо запустить новый поток, чтобы выполнить работу, либо запустить асинхронный код.
Для вас что-то вроде этого должно работать просто отлично:
public async void Form1_Load(object sender, EventArgs e) {
for (int i = 1; i < total; i++){
for (int row = 0; row < 4; row++){
for (int col = 0; col < 4; col++){
pixel = block[i][row][col];
label1.Text = pixel.R.ToString("X");
await Task.Delay();
}
}
}
}
Пока Sleep
блокирует поток во время ожидания, await Task.Delay();
делает не . Он фактически возвращает и позволяет потоку продолжать делать то, что он делал ранее, и уведомляет поток о завершении ожидания, чтобы поток мог позже вернуться к вашей функции и продолжить выполнение вашего кода. (Это упрощение работы асинхронных и ожидающих в C #)