Обновления WPF GUI выполняются в потоке GUI, но вы блокируете этот поток с помощью Thread.Sleep
в функции Start, которая вызывается обработчиком событий окна Loaded
, который сам вызывается потоком GUI.,Я вижу, что вы пытаетесь сделать с помощью функции DoEvents
, но это не надежный способ обновления потока GUI (вы уже находитесь в потоке GUI, поэтому вы полагаетесь на какой-то неизвестный внутреннийповедение фреймворка для принудительного обновления).
Параллельное программирование - это не тривиальная вещь, я бы порекомендовал вам прочитать об этом, прежде чем идти дальше.Для начала, вы никогда не должны звонить Thread.Sleep()
.Потоки устарели в C # и были заменены асинхронным программированием (которое может использовать или не использовать потоки внутри, но обычно это не касается разработчика приложения).Здесь вам нужно изменить асинхронную функцию «Пуск», например, примерно так:
private async Task Start()
{
for (int i = 0; i < MaxRow; i++)
{
for (int j = 0; j < MaxCol; j++)
{
string current = $"ImgR{i}C{j}";
object currentImg = this.FindName(current);
if (currentImg?.GetType() == typeof(Image))
{
var img = ((Image)currentImg);
await Task.Delay(TimeSpan.FromMilliseconds(1500));
Application.Current.Dispatcher.Invoke(() =>
{
img.Visibility = Visibility.Visible;
});
await Task.Delay(TimeSpan.FromMilliseconds(1500));
Application.Current.Dispatcher.Invoke(() =>
{
img.Visibility = Visibility.Hidden;
});
}
}
}
}
Затем в загруженной функции вы запускаете задачу с помощью:
private CancellationTokenSource CancelSource;
...
this.CancelSource = new CancellationTokenSource();
Task.Run(Start, this.CancelSource.Token);
ОтменаИсточник токена затем используется, если вам нужно отменить задачу, например, если пользователь закрывает окно:
this.CancelSource.Cancel();