我正在做一些MultiThreading但是表格在加载时暂停.
我试图显示表单,然后在后台它应该填充组合框而不暂停表单.
在我的Form_Load事件中,我有这个:
private void frmIni_Load(object sender, EventArgs e) { Application.DoEvents(); Thread threadOne = new Thread(GetServers); threadOne.Start(); }
在我的GetServers()方法中:
private void GetServers() { cboServer.BeginInvoke( (Action)(() => { servers = SmoApplication.EnumAvailableSqlServers(false); Thread.Sleep(1); foreach (DataRow server in servers.Rows) { cboServer.Properties.Items.Add(server["Name"]); Thread.Sleep(1); } })); }
我在这里错过了什么?表单不应该暂停,它应该工作,然后最终当线程完成时,它应该只填充组合框.
是的,它阻止UI的原因很简单,因为在新线程中没有运行真正的代码.在你打电话给GetServers
你的时候回到UI线程,然后做忙碌的事情(你可能根本就不用线程......).
您希望在线程中放置任何长时间运行的工作,并且只在想要更新它时回调到UI线程,例如
private void frmIni_Load(object sender, EventArgs e) { Task.Factory.StartNew(() => { return SmoApplication.EnumAvailableServers(false); }).ContinueWith((task) => { foreach (var server in task.Result) { cboServer.Properties.Items.Add(server["Name"]); } }, TaskScheduler.FromCurrentSynchronizationContext()); }
注意事项
DoEvents
尝试多线程时不要使用,特别是当您不了解它的用法时.
除非您确定需要(例如,长时间运行的I/O任务),否则不要启动新线程
不要Thread.Sleep
用来模拟"暂停"(你似乎在做)
使用线程池进行短期工作(像这样).