进度条正在跳跃

时间:2017-08-24 13:24:18

标签: c# wpf multithreading progress-bar

当我启动程序时,我需要加载一些项目并初始化它们。所以我在Thread中创建了所有内容并创建了一个进度条(下一个PB)。加载开始时,每个方面都可以,但是在一瞬间PB停止并在init结束时跳转到结束。

Progress bar

这里是每个init bLock添加到进度条的线程。

public void initMapBlocks(int n, int m)
    {
        this.Dispatcher.Invoke(delegate ()
        {
            Loader.Visibility = Visibility.Visible;
            mainWindow.Visibility = Visibility.Hidden;
        });
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                this.Dispatcher.Invoke(delegate ()
                {
                    MapPart mp = new MapPart();
                    mainCanvas.Children.Add(mp);
                    Loader.addPoint(1);
                });
            }
        }
        this.Dispatcher.Invoke(delegate ()
        {
            Loader.Visibility = Visibility.Hidden;
            mainWindow.Visibility = Visibility.Visible;
        });

    }

是否可以获得完整的动画?

--------更新--------
这里代码我添加到进度条值。

public void addPoint(int x)
    {
        itemCountAlready += x;
        loaderBar.Value += x;
    }

-----更新2 -------

private void Window_Loaded(object sender, RoutedEventArgs e)
    {

        Thread thread = new Thread(new ThreadStart(() => initMapBlocks(100, 100)));
        thread.Start();
    }

1 个答案:

答案 0 :(得分:3)

您的initMapBlocks方法同时产生(MapPart)并消耗(添加loader的值和mainCanvas子元素)。您可以使用System.Collections.Generic.Queue

分隔

您可以像这样定义队列

private Queue<MapPart> myQueue = new Queue<MapPart>();

而不是这些家伙

mainCanvas.Children.Add(mp);
Loader.addPoint(1);

你可以简单地为生产

写这个
myQueue.Enqueue(mp);

您可以在构造函数中定义DispatcherTimer以供使用

DispatcherTimer myTimer = new DispatcherTimer {
    Interval = TimeSpan.FromMilliseconds(1)
};
myTimer.Tick += Consume;
myTimer.Start();

您的Consume方法

private void Consume(object sender, EventArgs args) {
    if (myQueue.Count > 0) {
        //you don't need `this.Dispatcher.Invoke(delegate...` too
        loaderBar.Value += myQueue.Dequeue();
        mainCanvas.Children.Add(mp);
    }
}