C#中带单声道的交叉线程形式
我正在创建一个使用.Net和Mono的应用程序,它使用跨线程表单,因为我的子窗口响应不好 我用两个表单创建了一个测试程序:第一个表单(form1)有一个按钮(button1),第二个表单(form2)为空,代码片段如下C#中带单声道的交叉线程形式,c#,mono,multithreading,C#,Mono,Multithreading,我正在创建一个使用.Net和Mono的应用程序,它使用跨线程表单,因为我的子窗口响应不好 我用两个表单创建了一个测试程序:第一个表单(form1)有一个按钮(button1),第二个表单(form2)为空,代码片段如下 void openForm() { Form2 form2 = new Form2(); form2.ShowDialog(); } private void button1_Click(object sender, EventArgs e) { Thre
void openForm()
{
Form2 form2 = new Form2();
form2.ShowDialog();
}
private void button1_Click(object sender, EventArgs e)
{
Thread x = new Thread(openForm);
x.IsBackground = true;
x.Start();
}
这在.Net中运行良好,但在Mono中,当您单击第一个窗口(标准的.ShowDialog()行为)而不是.Net使用的.Show()行为时,第一个窗口将不会获得焦点
当我在.Net和Mono上使用.Show()时,窗口会闪烁然后消失。如果我将“MessageBox.Show()”放在“form2.Show()”之后,它将保持打开状态,直到您单击“确定”
我是在代码中遗漏了什么,还是Mono不支持?(我使用的是Mono 2.8.1)
提前谢谢你,阿德里安
编辑:我意识到我忘记了'x.IsBackground=true;'在上面的代码中,子窗口将与主窗口一起关闭。如果使用Winforms控件,则应始终在主UI线程中“触摸”对象 至少,在新线程中调用new Form.ShowDialog()没有意义 编辑: 如果希望轻松使用Invoke/BeginInvoke,可以使用扩展方法:
public static class ThreadingExtensions {
public static void SyncWithUI(this Control ctl, Action action) {
ctl.Invoke(action);
}
}
// usage:
void DoSomething( Form2 frm ) {
frm.SyncWithUI(()=>frm.Text = "Loading records ...");
// some time-consuming method
var records = GetDatabaseRecords();
frm.SyncWithUI(()=> {
foreach(var record in records) {
frm.AddRecord(record);
}
});
frm.SyncWithUI(()=>frm.Text = "Loading files ...");
// some other time-consuming method
var files = GetSomeFiles();
frm.SyncWithUI(()=>{
foreach(var file in files) {
frm.AddFile(file);
}
});
frm.SyncWithUI(()=>frm.Text = "Loading is complete.");
}
在Windows应用程序中,让多个线程与共享同一消息的一个或多个窗口进行对话几乎从来都不是正确的做法 而且很少需要有一个以上的消息泵 正确的方法是使用“Invoke”方法手动将工作线程中的所有内容封送回窗口,或者使用BackgroundWorker之类的方法,为您隐藏详细信息 总之:
- 不要为了耗时的计算或I/O而阻塞UI线程
- 不要从多个线程与UI对话