C#利用线程查询数据库数据,出现假死现象

emailqjc 2011-08-10 05:53:26
当数据库里数据量大的时候,查询会出现假死现象,代码如下,请各高人指导:
public partial class Form6 : Form
{
public delegate void myDelegate();

DataTable dt;

Thread tSo;

private MMS.Public.DbAccLibry.DbAccess mydbacc;

public Form6()
{
mydbacc = new MMS.Public.DbAccLibry.DbAccess();
mydbacc.DatabaseInint(MMS.Public.DbAccLibry.DataBaseType.MsSqlServer, "Server=192.192.192.8;Database=escashsystem;User ID=sa;Password=Hy@ecSun.cn;Connect Timeout=20;Pooling=True;Min Pool Size=1;Max Pool Size=100;Persist Security Info=False;Asynchronous Processing=true;Integrated Security=false;");

InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
try
{
tSo = new Thread(new ThreadStart(ThreadWork));
tSo.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString() + ",数据查询失败", "查询提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
}

void ThreadWork()
{
label2.BeginInvoke(new myDelegate (aa)) ;
this.dataGridView1.BeginInvoke(new myDelegate(FillData));//异步调用(来填充)

//this.Cursor = Cursors.Default;
label2.BeginInvoke(new myDelegate(bb));
}

private void FillData()
{
dt = mydbacc.ExecuteDataSet(CommandType.Text, "select * from ecv_spbaseinfo ").Tables[0];
this.dataGridView1.DataSource = dt.DefaultView;
}

private void aa()
{
this.label2.Text = "正在查询电价数据...";
}
private void bb()
{
this.label2.Text = "查询结束...";
}

}

...全文
589 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
CNCaiNiao 2012-07-05
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
建议改为:

public delegate void PDelegate(DataTable t);

void ThreadWork()
{
label2.BeginInvoke(new myDelegate (aa)) ;

DataTable dt = mydbacc.ExecuteDataSet(CommandType.Text, "select * fro……
[/Quote]

原来是用这种模式实现的,获取数据一个线程,填充又是另外一个线程,这样方面解决了“XXX不是线程的一部分”,又解决了卡死等待,强,非常感谢,最重要的是我这个菜鸟也能搞明白。
emailqjc 2011-08-12
  • 打赏
  • 举报
回复
顶一下啊
枫叶萧子 2011-08-11
  • 打赏
  • 举报
回复
受教了~~~~
emailqjc 2011-08-11
  • 打赏
  • 举报
回复
to 10楼:
你什么意思,不懂别乱发
dulei123321 2011-08-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 emailqjc 的回复:]

最后整理一下代码供大家分享:
public partial class Form6 : Form
{
public delegate void myDelegate(DataTable t);

public delegate void PDelegate();

DataTable dt;

……
[/Quote] +1
hhloong 2011-08-11
  • 打赏
  • 举报
回复
拿分 走人
emailqjc 2011-08-11
  • 打赏
  • 举报
回复
to stonespace:
我想终止查询,这样写可以吗?
/// <summary>
/// 终止查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
tSo.Abort();
}

emailqjc 2011-08-11
  • 打赏
  • 举报
回复
最后整理一下代码供大家分享:
public partial class Form6 : Form
{
public delegate void myDelegate(DataTable t);

public delegate void PDelegate();

DataTable dt;

Thread tSo;

private MMS.Public.DbAccLibry.DbAccess mydbacc;

public Form6()
{
mydbacc = new MMS.Public.DbAccLibry.DbAccess();
mydbacc.DatabaseInint(MMS.Public.DbAccLibry.DataBaseType.MsSqlServer, "Server=192.192.192.8;Database=escashsystem;User ID=sa;Password=Hy@ecSun.cn;Connect Timeout=20;Pooling=True;Min Pool Size=1;Max Pool Size=100;Persist Security Info=False;Asynchronous Processing=true;Integrated Security=false;");

InitializeComponent();
}

/// <summary>
/// 执行查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
try
{
tSo = new Thread(new ThreadStart(ThreadWork));
tSo.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString() + ",数据查询失败", "查询提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
}

/// <summary>
/// 终止查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
tSo.Abort();
}

void ThreadWork()
{
label2.BeginInvoke(new PDelegate(aa));

DataTable dt = mydbacc.ExecuteDataSet(CommandType.Text, "select * from ecv_spbaseinfo ").Tables[0];
this.dataGridView1.BeginInvoke(new myDelegate(FillData),new object[] { dt });//异步调用(来填充)

label2.BeginInvoke(new PDelegate(bb));
}

private void FillData(DataTable dt)
{
this.dataGridView1.DataSource = dt.DefaultView;
}

private void aa()
{
this.label2.Text = "正在查询电价数据...";
}
private void bb()
{
this.label2.Text = "查询结束";
}
}
jiayidan6 2011-08-11
  • 打赏
  • 举报
回复
进来学习!
沐NeMo 2011-08-11
  • 打赏
  • 举报
回复
学习了。ThreadWork本来就的从主程序分出来的线程了。还需要用new PDelegate() 来处理啊。
emailqjc 2011-08-11
  • 打赏
  • 举报
回复
非常感谢1楼的朋友,哪我如果想要终止查询,该怎么写呢
emailqjc 2011-08-11
  • 打赏
  • 举报
回复
首先感谢各位捧场,利用此地继续多线程问题讨论:
业务背景:
一家连锁超市,有上百家店,每家店可能有多台收银机,现在各门店,的收银机向总部服务器上的通讯服 务程序发送业务请求(通过此通讯服务程序向地三方公司发送送,并返回请求结果);
要求能高效快速向第三方公司发送各收银机的请求,考虑并发性
我的处理方法:
在超市总部通讯服务器上增加一张表TableA(门店号,收银机号,流水号,是否发送处理),记录各工作站点向第三方公司发送业务请求列表,在总部服务器程序里创建6个线程:
线程1-> 负责获取未发送处理的列表
线程2-> 发送处理请求列表中第1部分
线程3-> 发送处理请求列表中第2部分
线程4-> 发送处理请求列表中第3部分
线程5-> 发送处理请求列表中第4部分
线程6-> 发送处理请求列表中第5部分
备注:第n部分,是根据流水号来分割的

请问能不能实现高效果并发处理,附上代码:
public delegate void myDelegateA(string t);


/// <summary>
///取当前数字所在位置
/// </summary>
/// <param name="value">当前数字</param>
/// <param name="k">每段数字个数</param>
/// <returns></returns>
private int GetIndex(int value, int k)
{
int result = 0;

if ((value % k) == 0)
{
result = k;
}
else { result = value % k; }
return result;
}

private void SetListItem1(string a)
{
listBox1.Items.Add(a);
}

private void SetListItem2(string a)
{
listBox2.Items.Add(a);
}

private void SetListItem3(string a)
{
listBox3.Items.Add(a);
}

private void SetListItem4(string a)
{
listBox4.Items.Add(a);
}

private void SetListItem5(string a)
{
listBox5.Items.Add(a);
}

private void SetListItem6(string a)
{
listBox6.Items.Add(a);
}
private void button4_Click(object sender, EventArgs e)
{
Thread myMainThread = new Thread(new ThreadStart(MyMainMetod));
myMainThread.Start();

Thread thread1 = new Thread(new ThreadStart(Method1));
Thread thread2 = new Thread(new ThreadStart(Method2));
Thread thread3 = new Thread(new ThreadStart(Method3));
Thread thread4 = new Thread(new ThreadStart(Method4));
Thread thread5 = new Thread(new ThreadStart(Method5));
Thread thread6 = new Thread(new ThreadStart(Method6));
thread1.Start();
thread2.Start();
thread3.Start();
thread4.Start();
thread5.Start();
thread6.Start();
}

private void MyMainMetod()
{
int i = 1;
while (i<=300 )
{
mylist.Add(i.ToString() );
i++;
}
}

public void Method1()
{
while (true)
{
if (mylist.Count > 0)
{
strMess = mylist[0];
}
mylist.Remove(strMess);
if (GetIndex(Convert.ToInt16(strMess), 6) == 1)
{
listBox1.BeginInvoke(new myDelegateA(SetListItem1), strMess);
Thread.Sleep(200);
}
}
}

public void Method2()
{
while (true)
{
if (mylist.Count > 0)
{
strMess = mylist[0];
}
mylist.Remove(strMess);
if (GetIndex(Convert.ToInt16(strMess), 6) == 2)
{
listBox2.BeginInvoke(new myDelegateA(SetListItem2), strMess);
Thread.Sleep(200);
}
}
}
public void Method3()
{
while (true)
{
if (mylist.Count > 0)
{
strMess = mylist[0];
}
mylist.Remove(strMess);
if (GetIndex(Convert.ToInt16(strMess), 6) == 3)
{
listBox3.BeginInvoke(new myDelegateA(SetListItem3), strMess);
Thread.Sleep(200);
}
}
}
public void Method4()
{
while (true)
{
if (mylist.Count > 0)
{
strMess = mylist[0];
}
mylist.Remove(strMess);
if (GetIndex(Convert.ToInt16(strMess), 6) == 4)
{
listBox4.BeginInvoke(new myDelegateA(SetListItem4), strMess);
Thread.Sleep(200);
}
}
}
public void Method5()
{
while (true)
{
if (mylist.Count > 0)
{
strMess = mylist[0];
}
mylist.Remove(strMess);
if (GetIndex(Convert.ToInt16(strMess), 6) == 5)
{
listBox5.BeginInvoke(new myDelegateA(SetListItem5), strMess);
Thread.Sleep(200);
}
}
}
public void Method6()
{
while (true)
{
if (mylist.Count > 0)
{
strMess = mylist[0];
}
mylist.Remove(strMess);
if (GetIndex(Convert.ToInt16(strMess), 6) == 6)
{
listBox6.BeginInvoke(new myDelegateA(SetListItem6), strMess);
Thread.Sleep(200);
}
}
}

chxg99 2011-08-11
  • 打赏
  • 举报
回复
mark,学习!
stonespace 2011-08-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 emailqjc 的回复:]
to stonespace:
我想终止查询,这样写可以吗?
/// <summary>
/// 终止查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArg……
[/Quote]

Thread.Abort可以用,

如果用Abort方法,最好在线程ThreadWork里面抓ThreadAbortException异常,Abort会引发这个异常,

gw6328 2011-08-10
  • 打赏
  • 举报
回复
帮顶,学习。
stonespace 2011-08-10
  • 打赏
  • 举报
回复
建议改为:

public delegate void PDelegate(DataTable t);

void ThreadWork()
{
label2.BeginInvoke(new myDelegate (aa)) ;

DataTable dt = mydbacc.ExecuteDataSet(CommandType.Text, "select * from ecv_spbaseinfo ").Tables[0];
this.dataGridView1.BeginInvoke(new PDelegate(FillData),new object[]{dt});//异步调用(来填充)

//this.Cursor = Cursors.Default;
label2.BeginInvoke(new myDelegate(bb));
}


private void FillData(DataTable dt)
{
this.dataGridView1.DataSource = dt.DefaultView;
}
stonespace 2011-08-10
  • 打赏
  • 举报
回复
this.dataGridView1.BeginInvoke(new myDelegate(FillData));//异步调用(来填充)

这样做没有意义,因为BeginInvoke是在界面线程执行填充操作,填充应该是耗时操作,你这样做还不如不用线程,直接在界面线程填充,

111,094

社区成员

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

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

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