猿问

从Parallel.ForEach更新UI

我只是在尝试更新进度条,Parallel.ForEach应用程序似乎死机了。


尽管我已经尝试过Invoke按照其他帖子中的建议使用解决方案,但是我仍然遇到问题。


这是我的代码的简化版本:


public partial class Form1 : Form

{

    event EventHandler ReportProgress;


    class ProgressEvent : EventArgs

    {

        public int Total { get; set; }

        public int Current { get; set; }

    }


    public Form1()

    {

        InitializeComponent();

        ReportProgress += Form1_ReportProgress;

    }


    private void Form1_ReportProgress( object sender, EventArgs e )

    {

        var progress = e as ProgressEvent;

        if ( InvokeRequired )

        {

            this.Invoke( new Action( () => { progressBar.Maximum = progress.Total; progressBar.Value = progress.Current; } ) );

        }

    }


    private void buttonStart_Click( object sender, EventArgs e )

    {

        // Create a list with seed to be used later

        List<int> values = new List<int>() { };

        values.AddRange( Enumerable.Range( 1, 15 ) );


        var total = values.Count();

        var current = 0;


        Parallel.ForEach( values, v =>

        {

            Interlocked.Increment( ref current );


            var r = new Random( v );

            // Just sleep a little

            var sleep = r.Next( 10, 1000 );

            Thread.Sleep( sleep );


            // Update the progress bar

            ReportProgress( null, new ProgressEvent() { Current = current, Total = total } );

        }

        );


        MessageBox.Show( "Done " );

    }

}

该应用程序似乎已挂起,并且未显示“消息”框,而如果我删除事件生成(ReportProgress),一切都将正常运行,但是显然进度条根本不会更新。


慕慕森
浏览 153回答 2
2回答

白板的微信

您可以更改:this.Invoke(&nbsp;new&nbsp;Action(&nbsp;()&nbsp;=>&nbsp;{&nbsp;progressBar.Maximum&nbsp;=&nbsp;progress.Total;&nbsp;progressBar.Value&nbsp;=&nbsp;progress.Current;&nbsp;}&nbsp;)&nbsp;);至:this.BeginInvoke(&nbsp;new&nbsp;Action(&nbsp;()&nbsp;=>&nbsp;{&nbsp;progressBar.Maximum&nbsp;=&nbsp;progress.Total;&nbsp;progressBar.Value&nbsp;=&nbsp;progress.Current;&nbsp;}&nbsp;)&nbsp;);这将在异步线程上执行操作。
随时随地看视频慕课网APP
我要回答