调度程序不更新进度条WPF

ep6jt1vc  于 2023-05-01  发布在  其他
关注(0)|答案(1)|浏览(219)

我在WPF应用程序中使用以下代码来显示进度条:

XAML:

<Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Button Grid.Row="1" x:Name="btn_StartLengthyTask" Click="btn_StartLengthyTask_Click" Width="200" Height="30" >Start Lengthy Task</Button>
        <ProgressBar Grid.Row="2" x:Name="pb_LengthyTaskProgress" Margin="10,20"  Value="0" ></ProgressBar>
        <TextBlock Grid.Row="3" x:Name="lbl_CountDownTimer" HorizontalAlignment="Center" > 00:10</TextBlock>
        <TextBlock Grid.Row="4" x:Name="lbl_TaskStatus" >Status...</TextBlock>

C#:

private void btn_StartLengthyTask_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                lbl_TaskStatus.Text = "Starting long Task...";
                Thread.Sleep(1000);
                lbl_TaskStatus.Text = "In Progress...";
                pb_LengthyTaskProgress.Value = 0;
                Task.Run(() =>
                {
                    for (int i = 0; i < 100; i++)
                    {
                        Thread.Sleep(50);
                        this.Dispatcher.Invoke(() => //Use Dispather to Update UI Immediately  
                        {
                            var test = OMS.MyOrders.Model.MyOrderExecutor.ExportImages(true);//Method taking long time to response
                            pb_LengthyTaskProgress.Value = i;
                            lbl_CountDownTimer.Text = i.ToString();
                        });
                    }
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

**问题:**UI上的进度条没有更新。先谢谢你了

vxf3dgd4

vxf3dgd41#

永远不要调用Thread.Sleep。使用DispatcherTimer或async Click事件处理程序在循环中调用await Task.Delay(...)Dispatcher.Invoke不需要。将长时间运行的方法 Package 在等待的Task.Run调用中。

private async void btn_StartLengthyTask_Click(object sender, RoutedEventArgs e)
{
    lbl_TaskStatus.Text = "Starting long Task...";

    await Task.Delay(1000);

    lbl_TaskStatus.Text = "In Progress...";
    pb_LengthyTaskProgress.Value = 0;

    for (int i = 1; i <= 100; i++)
    {
        await Task.Delay(50);

        var test = await Task.Run(() =>
            OMS.MyOrders.Model.MyOrderExecutor.ExportImages(true));

        pb_LengthyTaskProgress.Value = i;
        lbl_CountDownTimer.Text = i.ToString();
    }
}

更新:似乎你只想对一个长时间运行的方法进行一次调用。然后,该方法应该通过IProgress接口报告进度:

public bool ExportImages(bool b, IProgress<double> p)
{
    // call p.Report
}

它的用法如下:

private async void btn_StartLengthyTask_Click(object sender, RoutedEventArgs e)
{
    lbl_TaskStatus.Text = "Starting long Task...";
    await Task.Delay(1000);
    lbl_TaskStatus.Text = "In Progress...";

    var progress = new Progress<double>();
    progress.ProgressChanged += (s, p) =>
    {
        pb_LengthyTaskProgress.Value = p;
        lbl_CountDownTimer.Text = p.ToString();
    };

    var result = await Task.Run(() =>
        OMS.MyOrders.Model.MyOrderExecutor.ExportImages(true, progress));
}

相关问题