如何通过异步调用更新列表框?

2024-06-19

我开发了一个 Windows 窗体 C# 应用程序,我只想通过分拆另一个线程来更新主窗体中列表框中的项目,而不阻塞 GUI 窗体。 由于线程无法访问列表框等表单实体,因此我想到使用委托。 下面的代码显示了我如何使用委托来完成该任务,但它阻止了 GUI 表单。所以我只想将其转换为异步委托,该委托可以更新列表框而不阻塞 GUI 表单

代表声明

 delegate void monitoringServiceDel();

呼叫代表

new monitoringServiceDel(monitoringService).BeginInvoke(null, null);

委托方法的实现

private void monitoringService()
{
        this.listEvents.Invoke(new MethodInvoker(delegate()
        {
            int i = 0 ;
            while (i<50)
            {

                listEvents.Items.Add("count :" + count++);
                Thread.Sleep(1000);
                i ++;
            }

        }));


}

对于 Win Forms,您需要使用控件Invoke http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx method:

在拥有控件的线程上执行指定的委托 底层窗口句柄

基本场景是:

  • 进行繁重的举重工作后台工作者 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx在非 UI 阻塞线程上检索所有项目。
  • On the BackgroundWorker.RunWorkerCompleted 事件 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkercompleted.aspx,使用控件的 Invoke 方法将项目添加到控件(在您的例子中为 ListBox)。

大致如下:

var bw = new BackgroundWorker();
bw.DoWork += (sender, args) => MethodToDoWork;
bw.RunWorkerCompleted += (sender, args) => MethodToUpdateControl;
bw.RunWorkerAsync();

这应该会让你朝着正确的方向前进。

编辑:工作示例

public List<string> MyList { get; set; }

private void button1_Click( object sender, EventArgs e )
{
    MyList = new List<string>();

    var bw = new BackgroundWorker();
    bw.DoWork += ( o, args ) => MethodToDoWork();
    bw.RunWorkerCompleted += ( o, args ) => MethodToUpdateControl();
    bw.RunWorkerAsync();
}

private void MethodToDoWork()
{
    for( int i = 0; i < 10; i++ )
    {
        MyList.Add( string.Format( "item {0}", i ) );
        System.Threading.Thread.Sleep( 100 );
    }
}

private void MethodToUpdateControl()
{
    // since the BackgroundWorker is designed to use
    // the form's UI thread on the RunWorkerCompleted
    // event, you should just be able to add the items
    // to the list box:
    listBox1.Items.AddRange( MyList.ToArray() );

    // the above should not block the UI, if it does
    // due to some other code, then use the ListBox's
    // Invoke method:
    // listBox1.Invoke( new Action( () => listBox1.Items.AddRange( MyList.ToArray() ) ) );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何通过异步调用更新列表框? 的相关文章

随机推荐