C# 如何使用backgroundworker打开表单?
我有一个mdi表单,其中包含一些子表单。其中一个表单的加载需要时间。我需要使用backgroundworker来加载此表单。我尝试了这段代码,但出现了跨线程错误。实际上,我不能通过backgroundworker为我的“表单”设置mdiParent。 任何帮助都将不胜感激 代码:C# 如何使用backgroundworker打开表单?,c#,multithreading,winforms,backgroundworker,C#,Multithreading,Winforms,Backgroundworker,我有一个mdi表单,其中包含一些子表单。其中一个表单的加载需要时间。我需要使用backgroundworker来加载此表单。我尝试了这段代码,但出现了跨线程错误。实际上,我不能通过backgroundworker为我的“表单”设置mdiParent。 任何帮助都将不胜感激 代码: private void tsmiNewExpense_Click(object sender, EventArgs e) { tss_lbl1.Text = "Loading...";
private void tsmiNewExpense_Click(object sender, EventArgs e)
{
tss_lbl1.Text = "Loading...";
if (!BW1.IsBusy)
{
BW1.RunWorkerAsync();
}
}
private void BW1_DoWork(object sender, DoWorkEventArgs e)
{
frmNewExpense frm = new frmNewExpense();
showChildForm(frm);
}
/// <summary>
/// Checks for one instance of this form is running
/// </summary>
/// <param name="frm">the form that will be shown.</param>
private void showChildForm(Form frm)
{
bool exists = false;
foreach (Form item in this.MdiChildren)
{
if (item.Name == frm.Name)
{
item.Activate();
item.StartPosition = FormStartPosition.CenterParent;
item.WindowState = formWindowState;
exists = true;
break;
}
}
if (!exists)
{
frm.MdiParent = this;//this line gets cross-thread error
frm.StartPosition = FormStartPosition.CenterParent;
frm.WindowState = formWindowState;
frm.Show();
}
}
private void tsmiNewExpense\u单击(对象发送方,事件参数e)
{
tss_lbl1.Text=“加载…”;
如果(!BW1.IsBusy)
{
BW1.RunWorkerAsync();
}
}
私有void BW1_DoWork(对象发送方,DoWorkEventArgs e)
{
frmNewExpense frm=新的frmNewExpense();
showChildForm(frm);
}
///
///检查此窗体的一个实例是否正在运行
///
///将显示的表单。
私人作废展示儿童表格(表格frm)
{
bool exists=false;
foreach(此.MdiChildren中的表单项)
{
如果(item.Name==frm.Name)
{
item.Activate();
item.StartPosition=FormStartPosition.CenterParent;
item.WindowState=formWindowState;
存在=真;
打破
}
}
如果(!存在)
{
frm.MdiParent=this;//此行获取跨线程错误
frm.StartPosition=FormStartPosition.CenterParent;
frm.WindowState=formWindowState;
frm.Show();
}
}
这是使用同步上下文更新表单的lblTimer标签:
政务司司长:
希望获得此帮助。必须在UI线程上创建控件和表单。您无法从其他线程安全地创建它们。由于子窗体本身的原因,您的子窗体不太可能需要很长时间才能加载。更可能的情况是,您在加载表单时正在加载数据。因此,使用后台线程加载数据,然后将数据封送回UI。您可以选择在加载数据之前或之后创建表单。@Enigmativity您说得对。没错。我错了。谢谢你的提示。:)
public partial class MainForm : Form
{
private readonly SynchronizationContext _context;
public MainForm()
{
InitializeComponent();
// the context of MainForm, main UI thread
// 1 Application has 1 main UI thread
_context = SynchronizationContext.Current;
}
private void BtnRunAnotherThreadClick(object sender, EventArgs e)
{
Task.Run(() =>
{
while (true)
{
Thread.Sleep(1000);
//lblTimer.Text = DateTime.Now.ToLongTimeString(); // no work
UpdateTimerInMainThread(); // work
}
});
}
private void UpdateTimerInMainThread()
{
//SynchronizationContext.Current, here, is context of running thread (Task)
_context.Post(SetTimer, DateTime.Now.ToLongTimeString());
}
public void SetTimer(object content)
{
lblTimer.Text = (string)content;
}
}