我有我真的不想在这一点上改写,旧的形式,所以我在做什么加载表格,然后加入它以新UI形式显示在面板上。这工作正常,但速度很慢。旧的表单会进行大量的数据加载和收集,效率不高。因此,大型记录最多需要30秒才能加载。如您所知,创建表单然后在加载旧表单时“锁定”主UI大约30秒。这是我试图阻止的行为。我想加载新表单,在空白面板中显示“加载”gif,然后一旦加载旧表单,请删除“加载”图像并将该表单添加为控件。C# - 跨线程操作 - 在线程创建控制,添加到主窗体
这里开始出现问题。
我试图创建一个后台工作,但是这会导致STA错误(旧形式有它自己的一些螺纹数据负载),因为我无法工人改为STA我停止了尝试。
我试图创建一个调用(而BeginInvoke),虽然这工作,它并没有真正加载旧形式的线程。它只是将它发送回UI线程并在那里完成工作。这又挂起了用户界面。 I.E .:不是我想要的。
我试图创建一个委托并触发其作为线程的事件,但我得到了相同的结果如下...
我创建一个线程,设置STA就可以了,开始它然后做了一段时间循环,DoEvents等待它完成。当然,这一切似乎都在向面板中添加表单,然后从“创建线程之外的线程”获取“Control'ChartForm'访问”。在此错误中,“ChartForm”是在线程中加载的旧图表。
我已经尝试了上面的方法,但我用来代替私有静态字段来保存旧形式的创建,然后一旦线程完成它添加到面板上。这是在while循环之后创建线程的方法。同样的错误。
所以,我用上面的方法在其他地方与数据表,并没有得到数据传回主线程与数据绑定使用的任何问题。我知道这有点不同,但我不认为这很难做到。
下面是我尝试使用的代码,似乎是最接近我想要的。
private static _ChartForm;
private void LoadPatientChart()
{
ClearMainPanel(); // Removes any loaded ChartForms from Panel
if (_Patient == null) // Test to make sure a patient is loaded
return;
loadingPanel.Visible = true; // Displays the "Loading" gif
Thread thread = new Thread(new ThreadStart(this.GetChartForm));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
while (thread.ThreadState != ThreadState.Stopped)
Application.DoEvents(); // Keeps the UI active and waits for the form to load
this.ChartPanel.Controls.Add(_ChartForm); // This is where the error is
loadingPanel.Visible = false; // Hide the "Loading" gif
}
private void GetChartForm()
{
ChartForm chartForm = new ChartForm(_Patient.AcctNum.ToString(), false);
chartForm.TopLevel = false;
chartForm.FormBorderStyle = FormBorderStyle.None;
chartForm.Dock = DockStyle.Fill;
chartForm.Visible = true;
_ChartForm = chartForm;
}
老实说,这就是我所害怕的。我知道UI需要在UI Thread上创建,我只是希望它不需要在那里创建。 –