C#线程的一个问题

OenAuth.Core 2009-07-15 09:26:07
我要在一个线程里面对数据进行处理,处理完成后,在主线程进行界面刷新。为了使数据同步我用了AutoResetEvent,如下:


//成员变量
AutoResetEvent m_arePda =null;

//加载PDA文件线程
private void LoadPdaFileThread()
{
Thread.Sleep(10000); //模拟大数据加载 ..
m_arePda.Set();
}
private void Form1_Load(object sender, EventArgs e)
{
m_arePda = new AutoResetEvent(false); //创建非终止事件

Thread trd = new Thread(LoadPdaFileThread);
trd.Start();

m_arePdaList.WaitOne();

//开始将数据在界面显示
...
}



问题:现在因为在FormLoad里面用到了m_arePdaList.WaitOne();这样的话,只有当线程执行完,主界面才能显示出来。

我想要的是 显示主界面(没数据的)->线程加载数据->主界面显示数据 这样的流程

我试过直接在线程里面刷新主界面,不过那个局限性太大,刷一两个控件(如进度条)还没问题,不过同时刷好几个控件的话(如在ListView加数据,又要改变按钮状态,又改变窗口提示文字等)要写很多委托。所以就想先把数据加完,再刷界面。请.NET牛人们不吝赐教。
...全文
102 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
OenAuth.Core 2009-07-15
  • 打赏
  • 举报
回复
LQknife 您好,谢谢你的回答,刚刚看了一下MSDN,并在我的程序里面试了一下。可行。呵呵。 都是自已常年排斥组件惹的祸啊~~~
LQknife 2009-07-15
  • 打赏
  • 举报
回复
解决办法一: m_arePda = new AutoResetEvent(false) 改为 m_arePda = new AutoResetEvent(true)就不会
阻塞主线程了
解决办法二:不用AutoResetEvent感觉有点画蛇添足,你开线程的原因就是要用来不使主界面阻塞
建议用backgroundworker组件,在dowork方法里取数据(这个方法里不能有对界面操作的代码),在completed事件里更新界面(事件名字可能不对,查查msdn吧)
OenAuth.Core 2009-07-15
  • 打赏
  • 举报
回复
fancejackl 您好

看来你误解我的意思了。你举的例子我明白,是用来更新界面了。而且可以把函数放在子线程里面来更新界面。
不过 一、我要显示的数据,不是显示时间这么简单。我必须要等子线程把数据加载成功后才显示。不然显示的内容肯定是不正确的。我的问题核心是“如何让主界面来等子线程结束,然后自己再把子线程计算的结果显示出来,在此过程中主界面是一直可以看到的。

二、如果我在子线程中直接刷新界面。那就回到我的题目了:我试过直接在线程里面刷新主界面,不过那个局限性太大,刷一两个控件(如进度条)还没问题,不过同时刷好几个控件的话(如在ListView加数据,又要改变按钮状态,又改变窗口提示文字等)要写很多委托
OenAuth.Core 2009-07-15
  • 打赏
  • 举报
回复
CGabriel 您好
不要用 WaitOne, 等数据加载完之后用 Control.BeginInvoke 或者 Control.Invoke.

那我用什么来等待数据加载完呢?
fancejackl 2009-07-15
  • 打赏
  • 举报
回复
private void fill_text1()
{
for (int i = 0; i < 10000; i++)
{
SetText(i.ToString(), DateTime.Now.ToString("hh:mm:ss ms"));
Thread.Sleep(100);
}
}
private void SetText(string text,string datetimes)
{
if (this.InvokeRequired)
{
this.Invoke(new SetTextCallback(SetText), new object[] {text,datetimes }); //
}
else
{

this.textBox1.Text = text; //记录当前值
this.txt_1_d2.Text = datetimes; //记录现在时间
}
}
private void fill_text2()
{
int i = 0;
while (i <= 20000)
{
SetText2(i.ToString(), DateTime.Now.ToString("hh:mm:ss ms"));
Thread.Sleep(100);
i++;
}
}
private void SetText2(string text, string datetimes)
{
if (this.InvokeRequired)
{
this.Invoke(new SetTextCallback(SetText2), new object[] { text, datetimes }); //
}
else
{
this.textBox2.Text = text; //记录当前值
this.txt_2_d2.Text = datetimes; //记录现在时间
}
}
CGabriel 2009-07-15
  • 打赏
  • 举报
回复
不要用 WaitOne, 等数据加载完之后用 Control.BeginInvoke 或者 Control.Invoke.

或者干脆用 BackgroundWorker
OenAuth.Core 2009-07-15
  • 打赏
  • 举报
回复
0210 感谢你的回答,用你的方法可行,不过总觉得投机取巧了点。望楼下高人补充。谢谢大家。若无人补充。6小时内结账。
abc1_2_3 2009-07-15
  • 打赏
  • 举报
回复
同问
OenAuth.Core 2009-07-15
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 0210 的回复:]
你不要一个个往List里加嘛,一次性加

比如全局List list1 = new List();

你不应该用list1.Add();
应该用list1 = list2;

list2是你线程里读取到的数据,这样只有你数据全部读取完全局的List才有数据,Timer才会显示
[/Quote]

-_-|||这么绝~~~试试
世宝宝 2009-07-15
  • 打赏
  • 举报
回复
你不要一个个往List里加嘛,一次性加

比如全局List list1 = new List();

你不应该用list1.Add();
应该用list1 = list2;

list2是你线程里读取到的数据,这样只有你数据全部读取完全局的List才有数据,Timer才会显示
OenAuth.Core 2009-07-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 0210 的回复:]
使用线程加载数据到变量里(比如List),然后使用一个Timer定时检测变量里是否有数据,如果有则显示出来,我想你那里主要是加载数据用时比较大。


[/Quote]

我现在就是在线程里面把数据加载到一个List<string>里面,然后想主线程等子线程把数据加载完成后,把List显示出来,用Timer会不会太浪费了?因为随着线程的执行,我的List里面的数据越来越多,那用Timer定时显示时,肯定要先清空以前显示的,然后把List全部显示出来??这样~~~有点小恐怖。呵呵

对你的回答表示感谢。
fancejackl 2009-07-15
  • 打赏
  • 举报
回复
自己可以 写个 显示Show的方法啊!然后在调用,我最近也在 编写 这些问题。关于线程 端口 和 接口 方面的程序
世宝宝 2009-07-15
  • 打赏
  • 举报
回复
使用线程加载数据到变量里(比如List),然后使用一个Timer定时检测变量里是否有数据,如果有则显示出来,我想你那里主要是加载数据用时比较大。

OenAuth.Core 2009-07-15
  • 打赏
  • 举报
回复
softlove03 感谢你的回答

不过 一、我写的是WINDOWS窗口控制(ActiveX)没有Shown事件
二、我在应用程序中用Shown试过了,效果不是很好。(我在线程加载数据时,会更新界面里的一个ProgressBar,可如果用Show事件后,进度条不到AutoResetEvent.set()后,它不会显示
  • 打赏
  • 举报
回复
将Load事件改为Shown事件
accpyy 2009-07-15
  • 打赏
  • 举报
回复
学习ing
十八道胡同 2009-07-15
  • 打赏
  • 举报
回复
友情帮顶

110,537

社区成员

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

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

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