WPF:为什么我的线程仅更新某些值

问题描述 投票:0回答:1

首先,我不存在线程不更新值的一般问题,它只是一个值。

我创建了一个由进度条组成的时钟。时钟背后的“引擎”是第二个线程:

Thread clock = new Thread(UpdateRelative);

clock.IsBackground = true;
clock.Start();

在我进入UpdateRelative()-方法之前,这是我的Xaml时钟:

<Grid>
    <Grid.DataContext>
        <vm:TimerVM/>
    </Grid.DataContext>
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,10,10,10">
        <Border BorderBrush="Gray" BorderThickness="1">
            <Label Content="Progress Bar Timer" FontFamily="Bold" FontSize="45" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Margin="0,0,0,20"/>
        </Border>
        <StackPanel>
            <Label Content="Seconds in this Minute:"/>
            <Grid Width="400" Height="25">
                <ProgressBar Value="{Binding SecondsInMinute}" />
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
                    <Run Text="{Binding SecondsInMinute, StringFormat=N0}"/><Run Text="%"/>
                </TextBlock>
            </Grid>
        </StackPanel>
        <StackPanel>
            <Label Content="Minutes in this hour:"/>
            <Grid Width="400" Height="25">
                <ProgressBar Value="{Binding MinutesInHour}" />
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
                    <Run Text="{Binding MinutesInHour, StringFormat=N0}"/><Run Text="%"/>
                </TextBlock>
            </Grid>
        </StackPanel>
        <StackPanel>
            <Label Content="Hours in this day:"/>
            <Grid Width="400" Height="25">
                <ProgressBar Value="{Binding HoursInDay}" />
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
                    <Run Text="{Binding HoursInDay, StringFormat=N0}"/><Run Text="%"/>
                </TextBlock>
            </Grid>
        </StackPanel>
        <StackPanel Margin="0,50,0,0">
            <Label Content="Time until timer finished:"/>
        </StackPanel>
        <Grid Width="400" Height="25">
            <ProgressBar Value="{Binding TimerInPercent}" />
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
                    <Run Text="{Binding TimerInPercent, StringFormat=N0}"/><Run Text="%"/>
            </TextBlock>
        </Grid>
    </StackPanel>
</Grid>

在程序中看起来像这样:

enter image description here

现在是方法:这由我的第二个线程执行:

private void UpdateRelative()
{
    bool x = false;
    while (true)
    {
        DateTime time = DateTime.Now;

        SecondsInMinute = time.Second / 0.6;
        MinutesInHour = time.Minute / 0.6;
        HoursInDay = time.Hour / 0.24;

        if (timerReady)
        {
            if (!x)
            {
                //TimerEnd is the current time plus 2 minutes
                TimerEnd = new DateTime(TimerYear, TimerMonth, TimerDay, TimerHour, TimerMin, TimerSec);

                TimerInPercent = 0;
                x = true;
                Start = DateTime.Now;
            }

            DateTime now = DateTime.Now;
            DateTime end = TimerEnd;

            var endTimeSpan = now - Start;

            TimeSpan entireTime = end - Start;

            TimerInPercent = (100 / entireTime.TotalSeconds) * endTimeSpan.TotalSeconds;
        }

        Thread.Sleep(timeout);
    }
}

一般的问题是TimerInPercent。我将其放在if语句中,因为在按下按钮后,它应该只开始更新。此刻,计时器的“结束时间”在启动程序2分钟后设置。虽然每个值本身都会更新(SecondsInMinuteMinutesInHourHoursInDayTimerInPercent),但在GUI中也仅更新前三个。

例如,我在8:30启动程序。计时器现在设置为8:32。现在,我按下“确定”按钮。调试时,我可以看到值TimerInPercent正在更改其值。但是,尽管有其他值,但该值不会在GUI中更新。

当我删除if语句并从头开始更新值时,它将在GUI中更新。

我的问题是:如果不是从头开始更新值,而是稍后(在我按下按钮之后),线程为什么不更新GUI中的值?

c# wpf multithreading
1个回答
1
投票

嗯,它既与绑定无关,也与WPF都不相关,与该行有关:

TimerInPercent = (100 / entireTime.TotalSeconds) * endTimeSpan.TotalSeconds

您正在尝试将整数100除以更大的值,这将导致0。

您可以用(100.0 / entireTime.TotalSeconds)尝试一下

还请确保将TimerInPercent定义为double

© www.soinside.com 2019 - 2024. All rights reserved.