都是多线程惹的祸!

pansha 2006-09-30 11:40:01
这两天在写一个网址检测程序。因为数量比较大所以不得不用多线程。
先从数据库读取网址,用多线程检测网址能否打开,因为要把检测的结果更新到数据库,所以出现的问题是并发访问数据库造成数据库死锁。请问该如何解决这个问题,谁有相关的多线程资料或代码吗?

...全文
174 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
LoveMango 2006-10-12
  • 打赏
  • 举报
回复
mark
zhiming99 2006-10-01
  • 打赏
  • 举报
回复
用独占锁不就行了
Aallonlin 2006-10-01
  • 打赏
  • 举报
回复
//应该是这个位置插入数据库发生死锁!
public void update_table(string id,string counts)
{
lock(this)
{
try
{
GetUrl.DataBase.ExecuteSql("update tablename set e_canopen =" + counts + " where id=" + id + ";");
}
catch
{
//MessageBox.Show(ee.Message);
}
}
}
#endregion

}
}
pansha 2006-10-01
  • 打赏
  • 举报
回复
用独占锁不就行了 ?能否说的详细点.

我的代码:

开始定义
ArrayList ThreadList = new ArrayList(); //存放线程的数组
int run_num = 0; //当前检测到第几条记录
int run_total = 0;//总检测记录条数
int n = 0;//线程数
Thread[] kk;//线程数组
DataSet ds;//暂存数据
DateTime dt1, dt2;//开始时间 结束时间
TimeSpan dt3;//时间间隔
bool isend = false;//检测是否结束
string sql_temp = "";//临时存储SQL语句
string id, url;// 当前记录ID URL



开始运行入口
//点击按钮开始运行
private void button1_Click(object sender, EventArgs e)
{

DataBase.OpenDb();
ds = GetUrl.DataBase.ExecuteSql4Ds("select id , url , e_canopen from tablename where e_canopen is null and id>=" + left_num.Text + " and id<=" + right_num.Text); //e_canopen is null and
//textBox3.Text = "select id , url , e_canopen from tablename where id>=" + left_num.Text + " and id<=" + right_num.Text;
//return;
run_total = ds.Tables[0].Rows.Count;
timer1.Interval = Convert.ToInt32(textBox4.Text);
timer1.Start();
progressBar1.Minimum = 0;
progressBar1.Maximum = run_total+1;
progressBar1.Value = 0;
label2.Text = "0/" + run_total.ToString();
label3.Text = progressBar1.Value.ToString();
dt1 = DateTime.Now;
s_time_value.Text = dt1.ToShortTimeString();
s_time_value.Refresh();
label2.Refresh();
label3.Refresh();
progressBar1.Refresh();
n = Convert.ToInt16(textBox2.Text);
kk = new Thread[n];
try
{
for (int i = 0; i < n; i++)
{
gethttpinfo gp = new gethttpinfo();
if (run_num < run_total)
{
id = ds.Tables[0].Rows[run_num][0].ToString();
url = ds.Tables[0].Rows[run_num][1].ToString();
gp.id = id;
gp.url = "http://" + url;
gp.ul = new updatetable(gp.update_table);
run_num++;
}
else
{
textBox3.Text = "检测完成!";
textBox3.Refresh();
break;
}
kk[i] = new Thread(new ThreadStart(gp.GetRequestString));

textBox3.Text = "No." + id + "\t" + url + "检测中.........\r \n " + textBox3.Text;
textBox3.Refresh();
ThreadList.Add(kk[i]);
kk[i].Start();
}
}
catch
{ }
}



时间间隔函数

private void timer1_Tick(object sender, EventArgs e)
{
isend = true;
try
{
for (int i = 0; i < ThreadList.Count; i++)
{
Thread o = (Thread)ThreadList[i];
if (o.ThreadState.ToString() == "Stopped")
{
if (progressBar1.Value < run_total)
{
isend = false;
progressBar1.Value++;
label3.Text = progressBar1.Value.ToString();
label3.Refresh();
progressBar1.Refresh();
gethttpinfo gp = new gethttpinfo();
id = ds.Tables[0].Rows[run_num][0].ToString();
url = ds.Tables[0].Rows[run_num][1].ToString();
gp.id = id;
gp.url = "http://" + url;
gp.ul = new updatetable(gp.update_table);
run_num++;

kk[i] = new Thread(new ThreadStart(gp.GetRequestString));
textBox3.Text = "No." + id + "\t" + url + "检测中.........\r \n " + textBox3.Text;
textBox3.Refresh();
kk[i].Start();
ThreadList[i] = kk[i];
}

//ThreadList.RemoveAt(i--);
}
else
{
isend = false;
}
}
if (isend == true && run_num>=run_total)
{
timer1.Stop();
textBox3.Text = "检测完毕";
textBox3.Refresh();
progressBar1.Value = 0;
progressBar1.Refresh();
dt2=DateTime.Now;
dt3=dt2-dt1;
e_time_value.Text = dt2.ToShortTimeString();
run_time.Text = dt3.TotalSeconds.ToString() + "秒";
e_time_value.Refresh();
run_time.Refresh();
}
}
catch
{

}
}

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;

namespace GetUrl
{
public delegate void updatetable(string id, string counts);
public class gethttpinfo
{
public string id,url;
public updatetable ul;
public gethttpinfo()
{
}

#region 获取指定远程网页内容
/// <summary>
/// 获取指定远程网页内容
/// </summary>
/// <param name="strUrl">所要查找的远程网页地址</param>
/// <param name="timeout">超时时长设置,一般设置为8000</param>
/// <param name="enterType">是否输出换行符,0不输出,1输出文本框换行</param>
/// <param name="EnCodeType">编码方式</param>
/// <returns></returns>
/// 也可考虑 static string

public void GetRequestString()
{

int timeout = 15000, enterType = 1;
Encoding EnCodeType = Encoding.Default;

// string strResult;
try
{
HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(url);
myReq.Timeout = timeout;
HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
Stream myStream = HttpWResp.GetResponseStream();
StreamReader sr = new StreamReader(myStream, EnCodeType);
StringBuilder strBuilder = new StringBuilder();
while (-1 != sr.Peek())
{
strBuilder.Append(sr.ReadLine());
if (enterType == 1)
{
strBuilder.Append("\r\n");
}
}
ul(id, strBuilder.ToString().Length.ToString());
}
catch
{
//return 0;
}
}

//应该是这个位置插入数据库发生死锁!
public void update_table(string id,string counts)
{
try
{
GetUrl.DataBase.ExecuteSql("update tablename set e_canopen =" + counts + " where id=" + id + ";");
}
catch
{
//MessageBox.Show(ee.Message);
}
}
#endregion
}
}

110,539

社区成员

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

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

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