Winform异步Show Form问题
本帖最后由 cxy0303 于 2010-12-17 11:24:10 编辑 我们项目是启动程序时,有2个Form,一个MainForm,一个LoginForm
LoginForm是在MainForm 的Form_Load事件的ShowDialog的,现在为了加快程序运行速度,在Form_Load里我用BeginInvoke另外做了一些事为了让用户点击登陆界面后快速反映,经过我查看代码,发现点击LoginForm的登陆按钮后,实际上MainForm里还有一个Form叫NavigateForm,这个Form控件多,发现Show出来时耗时,因此BeginInvoke里我做的就是这件事,可以结果运行程序时,LoginForm呈现出来了,但是要等几秒才可以使用
大致结构就是
MainForm的Form_Load里做了2件事,一是LoginForm ShowDialog,二是异步Show NavigateForm
请大家提供的思路,有啥好解决的方法
[最优解释]
异步不行就用同步呗。多线程的话你执行另一个方法时对当前方法没多大影响。异步这种按我的理解你还不是在当前线程执行么。对其他和自己同线程执行的方法有什么好处?
[其他解释]
话说我不知道自己理解的对不对。等高手指点。
[其他解释]
不懂帮顶
[其他解释]
一般的情况下建议是在主线程里面来显示界面,在另外的线程当中来加载界面中的数据。
如果是单纯加载界面的话,不用几秒钟这么长吧,一般的情况下几十个控件不加载数据不绑定参数的话,1-2秒钟之类完全可以显示完成的。下载数据,绑定参数的操作你用另外的线程解决吧
如果硬要将界面显示放在线程里面来做的话,尝试着把线程的优先级提高试一下
[其他解释]
该回复于2010-12-17 13:24:02被版主删除
[其他解释]
2楼说的有点道理
[其他解释]
关键是登陆时呈现的哪个form耗事件,我就想在程序启动时,先show了一下在隐藏掉,这样,点登陆后界面能立马跳出来
[其他解释]
所以说建议你吧那个耗时间的窗体show委托在新线程里面执行啊
[其他解释]
好东西哦
[其他解释]
我是用的新线程,BeginInvoke就是啊。。,或者自己不用BeginInvoke,另外写个线程把项目所有form都show下在销毁,是否能解决winform窗体第一次运行慢的问题呵呵
[其他解释]
你为什么不用 LoginForm 做为启动窗口呢? 当登陆成功 将 LoginForm 做为参数 传给 MainForm
然后在 MainForm 的 formclosing 事件里面 加上 LoginForm.close
并且将 MainForm 的 Form_Load 事件里面的代码写为一个方法 比如 Main_Load
在 LoginForm 窗体里面
MainForm mf = new MainForm();
mf.Main_Load();
mf.show();
这个更加平滑!!!
不知道 我有没有理解错楼主的意思
[其他解释]
对begininvoke了解不深。以前只知道新建线程出来就算个多线程。而且一直都是这样做,begininvoke只是在需要用多线程调用基础窗体线程下的控件才用到。9楼的方法不错。只是不要lognform里面调用主窗体。那样的话lognform关闭时主窗体也会关闭。
[其他解释]
不关闭 login 窗体 把它隐藏就好了,在关闭 main 窗体的时候 在把login 关闭掉
[其他解释]
这个是我们公司最近开发的一个项目 这个是登陆的窗体代码
//主窗体启动
SysMian sys = new SysMian(this);
sys.Win_Show();
this.Hide();
sys.Show();
这个是 SysMian 窗体的代码
Login _WinLogin;
public SysMian(Login WinLogin)
{
_WinLogin = WinLogin;
InitializeComponent();
}
//窗体启动时必须调用
public void Win_Show()
{
laddr1.Text = "";
laddr2.Text = "";
GlobalVariables.RecformatUrl = Application.StartupPath + @"\users\" + GlobalVariables.Username + @"\Sound\";
if (!Directory.Exists(GlobalVariables.RecformatUrl))
Directory.CreateDirectory(GlobalVariables.RecformatUrl);
toolCALLLOG.PerformClick();
new DBbase().Data_Load();//初始化数据库文件
OpenCTIBox();//启动硬件设备
_Calllog();
}
//主窗口关闭时 同时关闭登陆窗口
private void SysMian_FormClosing(object sender, FormClosingEventArgs e)
{
if (!Leiku.Pub.ShowMess_OKCancel("你确定要关闭软件吗???"))
{
e.Cancel = true;
}
else
{
//停止声卡占用
usbport.GXusb.GX_StopMonitorSound();
//关闭所有通道
for (int i = 0; i < TotalVoiceChannel; i++)
{
usbport.GXusb.GX_CloseChannel(Convert.ToUInt16(i));
}
usbport.GXusb.GX_CloseSystem().ToString();
SystemLog();
_WinLogin.Close();
}
}
希望对楼主有所启发
[其他解释]
异步同步必须是两个线程对比才有意义;主线程调用自己的invoke或者 begininvoke,只能算同一线程里的代码在插队执行(主线程要等待插队的代码先执行),整个过程始终都是同步(没有多线程对比其实还说不上是同步异步);应该新建一个线程ThreadNew,新线程如果需要同主线程交互,则调用主线程的invoke(或begininvoke)对主线程插队;调用invoke时,ThreadNew必须等待主线程执行完invoke(同步);
调用begininvoke时,ThreadNew不用等待主线程执行完begininvoke就可以继续执行ThreadNew里后面的程序(异步)