我已经开发了一个Windows窗体c#应用程序,我只想在主窗体中的列表框中更新项目,通过旋转另一个线程而不阻止GUI窗体.由于线程无法访问像listbox这样的表单实体,我想到了使用委托.下面的代码显示了我如何使用委托来执行该任务,但它阻止了GUI表单.所以我只想将它转换为异步委托,更新列表框而不阻止GUI表单
代表声明
delegate void monitoringServiceDel();
Run Code Online (Sandbox Code Playgroud)
打电话给代表
new monitoringServiceDel(monitoringService).BeginInvoke(null, null);
Run Code Online (Sandbox Code Playgroud)
委托方法实现
private void monitoringService()
{
this.listEvents.Invoke(new MethodInvoker(delegate()
{
int i = 0 ;
while (i<50)
{
listEvents.Items.Add("count :" + count++);
Thread.Sleep(1000);
i ++;
}
}));
}
Run Code Online (Sandbox Code Playgroud)
对于Win Forms,您需要使用Control的Invoke方法:
在拥有控件的基础窗口句柄的线程上执行指定的委托
基本情景是:
有点像:
var bw = new BackgroundWorker();
bw.DoWork += (sender, args) => MethodToDoWork;
bw.RunWorkerCompleted += (sender, args) => MethodToUpdateControl;
bw.RunWorkerAsync();
Run Code Online (Sandbox Code Playgroud)
这应该让你朝着正确的方向前进.
编辑:工作样本
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() ) ) );
}
Run Code Online (Sandbox Code Playgroud)