明明调用了多线程和invoke了,怎么form_load的时候还是假死?

beyondjay 2007-04-07 09:43:31
在formload的时候要检查数据库连接的状态,这个时间比较长,所以想先让form show出来,等检查完的时候自动跳出提示。但是现在虽然开了多线程还是会程假死的状态,鼠标编程漏斗,怎么会这样子阿?

private void MainForm_Load(object sender, System.EventArgs e)
{
this.Show();
System.Threading.Thread myThread = new System.Threading.Thread(new System.Threading.ThreadStart(threadone));
myThread.Start();
}

private void threadone()
{
this.BeginInvoke(new aa_d(CheckConfig));
}

private void CheckConfig()
{
//大量操作
}
真是奇怪阿,大侠帮忙看看阿!
...全文
700 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
wzq6511 2007-04-25
  • 打赏
  • 举报
回复
mark
chenanlin1981 2007-04-25
  • 打赏
  • 举报
回复
mark
ufoteam 2007-04-25
  • 打赏
  • 举报
回复
总之//大量操作应/该放在BeginInvoke之前。否则就一样会去到UI线程中处理,跟没BeginInvoke效果一样
private void threadone()
{
//大量操作
this.BeginInvoke(new aa_d(CheckConfig));
}

private void CheckConfig()
{
//这里只能做一些更新操作
}
ufoteam 2007-04-25
  • 打赏
  • 举报
回复
回复人:superbug1984(每天坚持灌下水,这样才有内裤穿 :D)

看来是你错,它的this.Show();虽然是多于的,但一点都不影响他的程序
erental 2007-04-10
  • 打赏
  • 举报
回复
mark
liujiwe79 2007-04-10
  • 打赏
  • 举报
回复
application.doevents
GXY2005 2007-04-10
  • 打赏
  • 举报
回复
如果多线程代码正确,依然假死,那么就是你线程任务太重,可添加System.threading.thread.sleep(100);这样的语句让CPU有空闲处理其它事务!
bbbbbb888888 2007-04-10
  • 打赏
  • 举报
回复
mark
superbug1984 2007-04-08
  • 打赏
  • 举报
回复
ls估计没看明白

lz的代码是这样的
private void MainForm_Load(object sender, System.EventArgs e)
{
this.Show();//注意这行
System.Threading.Thread myThread = new System.Threading.Thread(new System.Threading.ThreadStart(threadone));
myThread.Start();
}

private void threadone()
{
this.BeginInvoke(new aa_d(CheckConfig));
}

private void CheckConfig()
{
//大量操作
}

我不明白为什么在MainForm_Load方法里还来一行this.Show();??这样的话不就相当于又重新执行一遍MainForm_Load?把这行删掉!

还有个建议就是将线程的后台属性设为true,即myThread.IsBackground = true;加上去
另外,BeginInvoke是没有错的,只是在这里没有必要。
superbug1984 2007-04-08
  • 打赏
  • 举报
回复
to winner2050

你说的代码我测试过了是可以的
Jinwmmail 2007-04-08
  • 打赏
  • 举报
回复
superbug 的方案, 再在下面加点:

private void CheckConfig()
{
//大量操作

Thread.Sleep(20)
}
james_hunter 2007-04-08
  • 打赏
  • 举报
回复
superbug 一针见血。
winner2050 2007-04-08
  • 打赏
  • 举报
回复
请问楼上,你代码里面的.
private void SetText(string text)
{
if (this.txtMsgStatus.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.txtMsgStatus.Text += text;
}
}

我有个代码跟你的这个基本一样,但是类似
this.txtMsgStatus.Text += text;
实际运行效果跟this.txtMsgStatus.Text = text;一样
令我郁闷无比,要实现this.txtMsgStatus.Text += text;要注意什么呢?
我搞winform很少,请教一下.
ufoteam 2007-04-07
  • 打赏
  • 举报
回复
private void threadone()
{

for(int i=0;i<10000;i++)
{
...大量计算操作
}
this.BeginInvoke(new aa_d(CheckConfig));

}
private void CheckConfig()
{
textBox1.Text="操作结果";
}
ufoteam 2007-04-07
  • 打赏
  • 举报
回复
你的大量操作应该在private void threadone() 中实现,
到最后更新控件的操作才转到private void CheckConfig()中操作
按照你的方法,实质上将大量操作线程经过最终都是转回给ui线程处理,反而操作是多余的
hertcloud 2007-04-07
  • 打赏
  • 举报
回复
//多线程间 控件的操作例子
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Data.SqlClient;
using System.Collections;

namespace AutoMessager
{
delegate void myDelegate();
delegate void SetTextCallback(string text);

public partial class frmAutoMsg : Form
{
event myDelegate myEvent;
string connStr = string.Empty;
Thread thd;
//private Icon eyeIcon;

//private NotifyIconEx notifyIconA;
//private NotifyIconEx notifyIconB;
private bool canClosed = false;

public frmAutoMsg()
{
this.ShowInTaskbar = false;
InitializeComponent();
//eyeIcon = new Icon(GetType(), "EYE.ICO");
notifyIcon1.ContextMenu = contextMenuB;
}

private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.txtMsgStatus.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.txtMsgStatus.Text += text;
}
}


private void frmAutoMsg_Load(object sender, EventArgs e)
{
connStr = System.Configuration.ConfigurationManager.AppSettings["ConnString"];
thd = new Thread(new ThreadStart(doEvent));
thd.IsBackground = true;
thd.Start();
//doEvent();
//notifyIcon1.Visible = true;
}

/// <summary>
/// 员工合同到期提醒
/// </summary>
void UpUserState()
{
SqlConnection conn = null;
DateTime now = DateTime.Now;
SqlTransaction tran = null;
SqlDataReader dr = null;
try
{
//数据库操作部分省略

SetText("\r\n系统提示: 职员合同消息更新成功!\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");


}
catch (Exception ex)
{
dr.Close();
tran.Rollback();
SetText("\r\n系统错误: 职员合同消息更新错误:" + ex.Message + "\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");
}
finally
{
dr.Close();
conn.Close();
conn.Dispose();
}
}
/// <summary>
/// 采购及供货 到货提醒
/// </summary>
void UpCaiGou()
{
SqlConnection conn = null;
DateTime now = DateTime.Now;
SqlTransaction tran = null;
SqlDataReader dr = null;
try
{
//数据库操作部分省略

SetText("系统提示: 合同采购消息更新成功!\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");


}
catch (Exception ex)
{
dr.Close();
tran.Rollback();
SetText("系统错误: 合同采购消息更新错误:" + ex.Message + "\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");
}
finally
{
dr.Close();
conn.Close();
conn.Dispose();
}
}

/// <summary>
/// 供货收款情况提醒
/// </summary>
void GetMoney()
{
SqlConnection conn = null;
DateTime now = DateTime.Now;
try
{
//数据库操作部分省略
SetText("系统提示: 供货付款消息更新成功!\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");
}
catch (Exception ex)
{
SetText("系统错误: 供货付款消息更新错误:" + ex.Message + "\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");
}
finally
{
conn.Close();
conn.Dispose();
}
}

void doEvent()
{
//int weather = int.Parse(weatherTime.Text);
//int del = int.Parse(fileTime.Text);
// if(weather < 1 || weather > 24 || del < 1 || del > 24)
// {
// MessageBox.Show("时间输入有错!");
// button1.Enabled = true;
// return ;
// }
while (true)
{

//DateTime now = DateTime.Now;
int i = DateTime.Now.Hour;
if (i > 2 && i < 4)
{
myEvent = new myDelegate(UpUserState);
myEvent += new myDelegate(UpCaiGou);
// myEvent += new myDelegate(GetMoney);
}
//if (now.Hour == 3)
//{
// myEventB = new myDelegate(deltemp);
//}
//if (myEventA != null) myEventA();
//if (myEventB != null) myEventB();
if (myEvent != null)
{
myEvent();
myEvent = null;
}
Application.DoEvents();

Thread.Sleep(6000000); //每100分钟检查一次时间
}
}

private void frmAutoMsg_FormClosing(object sender, FormClosingEventArgs e)
{
if (canClosed == false)
{
e.Cancel = true;
this.Hide();
this.Visible = false;
//this.
}
}

private void menuItem2_Click(object sender, EventArgs e)
{
this.ShowInTaskbar = true;
this.Show();
this.Visible = true; //恢复主窗体
}

private void menuItem1_Click(object sender, EventArgs e)
{
canClosed = true;
Application.Exit();
}

private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.ShowInTaskbar = true;
this.Show();
if (this.Visible == false)
{
this.Visible = true;
}

}

private void btnClear_Click(object sender, EventArgs e)
{
this.txtMsgStatus.Text = "";
}

private void btnUpMsg_Click(object sender, EventArgs e)
{
myEvent = new myDelegate(UpUserState);
myEvent += new myDelegate(UpCaiGou);
//myEvent += new myDelegate(GetMoney);

if (myEvent != null)
myEvent();
}
}
}
kissknife 2007-04-07
  • 打赏
  • 举报
回复
CheckConfig()
中添加sleep
如sleep(20)
winxieddd 2007-04-07
  • 打赏
  • 举报
回复
是这样更新控件的。:)
winxieddd 2007-04-07
  • 打赏
  • 举报
回复
private void 更新界面()
{
if(this.InvokeRequired)
{
this.Invoke(new aa_d(更新界面));
}
textBox1.Text = "初始化完毕!";
}
beyondjay 2007-04-07
  • 打赏
  • 举报
回复
不是说新线程没办法更新控件的嘛,怎么又可以了,真是奇怪阿
加载更多回复(1)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧