线程池,异步的一个小问题!

l171147904 2010-03-09 04:30:18
原贴:http://topic.csdn.net/u/20100308/11/90648743-1e22-48cd-b69a-29d895b6310b.html

使用15楼方法:
MyData de = new MyData();
private void Form1_Load(object sender, EventArgs e)
{
int[,] data = new int[,] { { 100, 1 }, { 200, 1 }, { 500, 0 }, { 1000, 1 } };

for (int i = 0; i < 4; i++)
{
MyData de = new MyData();
de.waittime = data[i, 0];
de.value = data[i, 1];
ThreadPool.QueueUserWorkItem(new WaitCallback(JanitorMethod), de);
}
}

private void JanitorMethod(object ob)
{
this.de = (MyData)ob;
Thread.Sleep(de.waittime);
Console.WriteLine("等待" + de.waittime + "后, 取值:" + de.value);
}

struct MyData
{
public int waittime;
public int value;
}
假定:
延迟 数据
200 1
500 2
1000 3
2000 4

第一笔和最后一笔数据处理准确!
2,3笔数据处理,我跟踪SQL语法,都是 执行第四笔的数据!

输出结果:1,4,4,4
...全文
230 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
l171147904 2010-03-17
  • 打赏
  • 举报
回复
l171147904 2010-03-12
  • 打赏
  • 举报
回复
虽然没上锁,问题OK!
既然你说到这问题,我顺便问问!可能我对上锁概念不清晰!

上锁:本线程结束前,禁止别的线程调用该代码!

线程1上锁了,处理睡觉状态(1线程 1000)
2线程,要进来处理(2线程 500),它能进来处理???

这样是否造成 实现不了我需要的 各自处理效果?
archu 2010-03-09
  • 打赏
  • 举报
回复
引用 12 楼 archu 的回复:
因为你第1个线程才sleep了100毫秒,足够快,第1个线程还没来得及修改de的值。


更正如下:

因为你第1个线程才sleep了100毫秒,足够快,第2个线程还没来得及修改de的值。
archu 2010-03-09
  • 打赏
  • 举报
回复
你这样的代码出错很正常。
就拿第1、2两个线程来举例子,假设第2个线程是在第1个线程创建之后立马就创建了,那么……

1. 线程1开始睡觉,还没有睡完的时候……
2. 线程2进来了,并修改了de的值
3. 线程1睡醒了,开始打印数据,这时候打印的数据当然是第2组数据咯

再来说说为什么你打印的是1,4,4,4
因为你第1个线程才sleep了100毫秒,足够快,第1个线程还没来得及修改de的值。
而对于第2、3个线程来说,它们在sleep的时候被线程4修改了数据。

结论:
不同的线程你要是操作相同的对象的话,记得上锁(做好同步),否则出现这种现象很正常
l171147904 2010-03-09
  • 打赏
  • 举报
回复
谢谢大家帮忙!尤其

枫中玫瑰,x∈(-∞,+∞)) ,guoyichao

原因不明!修正 全部变量任然错误!

用7楼:
private void JanitorMethod(object ob)
{
MyData de = (MyData)ob;
Thread.Sleep(de.waittime);
Console.WriteLine("等待" + de.waittime + "后, 取值:" + de.value);
}

正确!!!
l171147904 2010-03-09
  • 打赏
  • 举报
回复
好像!不是这原因!或者还有别的原因

修改全局变量为 de_All

当前结果:
update TT set value=1 where id='a';
update TT set value=3 where id='c';
update TT set value=3 where id='c';
update TT set value=3 where id='c';
l171147904 2010-03-09
  • 打赏
  • 举报
回复


我看看,我怎么就没注意!大意了。。。
qqiuzaihui 2010-03-09
  • 打赏
  • 举报
回复
引用 5 楼 cherishny 的回复:
MyData de = new MyData();全局变量

for (int i = 0; i < 4; i++)
            {
MyData de = new MyData(); 局部变量
                de.waittime = data[i, 0];
                de.value = data[i, 1];
                ThreadPool.QueueUserWorkItem(new WaitCallback(JanitorMethod), de);
            }


应该是这个问题, . 当时随手写的. 呵呵, 楼主自己再试试吧. 下班了.
guoyichao 2010-03-09
  • 打赏
  • 举报
回复
private void JanitorMethod(object ob)
{
MyData de = (MyData)ob;
Thread.Sleep(de.waittime);
Console.WriteLine("等待" + de.waittime + "后, 取值:" + de.value);
}
qqiuzaihui 2010-03-09
  • 打赏
  • 举报
回复
        private void Form1_Load(object sender, EventArgs e)
{
Console.WriteLine(DateTime.Now.ToLongTimeString());
int[,] data = new int[,] { { 100, 1 }, { 200, 2 }, { 500, 3 }, { 1000, 4 } ,
{200, 5},{500, 6},{1000, 7},{2000, 8 }};

for (int i = 0; i < 8; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(JanitorMethod), new MyData(data[i, 0], data[i, 1]));
}
}

private void JanitorMethod(object ob)
{
MyData de = (MyData)ob;
Thread.Sleep(de.waittime);
Console.WriteLine("等待" + de.waittime + "后, 取值:" + de.value + " 时间:" + DateTime.Now.ToLongTimeString());
}

struct MyData
{
public int waittime;
public int value;
public MyData(int time, int v)
{
waittime = time;
value = v;
}
}


估计是全局变量 de 的问题, 你改用这个试试. 应该可以的.
Cherishny 2010-03-09
  • 打赏
  • 举报
回复
MyData de = new MyData();全局变量

for (int i = 0; i < 4; i++)
{
MyData de = new MyData(); 局部变量
de.waittime = data[i, 0];
de.value = data[i, 1];
ThreadPool.QueueUserWorkItem(new WaitCallback(JanitorMethod), de);
}
l171147904 2010-03-09
  • 打赏
  • 举报
回复
正常SQL:
update TT set value=1 where id='a';
update TT set value=2 where id='b';
update TT set value=3 where id='c';
update TT set value=4 where id='d';
现在的语法:
update TT set value=1 where id='a';
update TT set value=4 where id='d';
update TT set value=4 where id='d';
update TT set value=4 where id='d';


使用我原来的多线程,能解决问题!但不知道怎么在数据操作完成后挂起线程!
dopsop110 2010-03-09
  • 打赏
  • 举报
回复
呵呵帮顶。。关注!。。。。
calltaotao 2010-03-09
  • 打赏
  • 举报
回复
楼主数据传错了,检查代码。
群龙 2010-03-09
  • 打赏
  • 举报
回复
这是什么意思...




回复内容 回复内容太短了!

110,539

社区成员

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

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

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