C#中多线程的问题,大家快帮帮忙,我搞晕了

IBM___ 2005-11-23 09:37:18
各位大虾:
Form1里有两个Button一个label1,点button1后启动另一个线程来生成一个Class2的对像,Class2中有个timer每隔500ms使i加一,并通过Form1的Label显示出来;点button2后不启动另一个线程,直接生成一个Class2的对像。为什么点button1不管用也不提示错误,Form1中的Label未变化。而点button2后正常??????????
代码如下

//---------------------Form1-------------------------

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;

namespace WindowsApplication2
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label1;
public static System.Windows.Forms.Label label_S;
private System.Windows.Forms.Button button2;
private System.ComponentModel.IContainer components;
public Form1()
{
InitializeComponent();
Form1.label_S=this.label1;
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(80, 16);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// label1
//
this.label1.Location = new System.Drawing.Point(72, 104);
this.label1.Name = "label1";
this.label1.TabIndex = 1;
this.label1.Text = "label1";
//
// button2
//
this.button2.Location = new System.Drawing.Point(208, 32);
this.button2.Name = "button2";
this.button2.TabIndex = 2;
this.button2.Text = "button2";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.button2);
this.Controls.Add(this.label1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
public static void TheadS()
{
Class1 c1=new Class1();
c1.Start();
}
private void button1_Click(object sender, System.EventArgs e)
{
Thread td=new Thread(new ThreadStart(TheadS));//创建另一个线程启动Label并无变化。
td.Start();
}

private void button2_Click(object sender, System.EventArgs e)
{
TheadS();// 直接启动显示正常。
}
}
}

//--------------------Class1---------------------
using System;
using System.Windows.Forms;
namespace WindowsApplication2
{
public class Class1
{
private System.Windows.Forms.Timer timer1=new Timer();
private int i=0;
public Class1()
{
this.timer1.Tick+=new EventHandler(timer1_Tick);
this.timer1.Interval=500;

}
public void Start()
{
this.timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
Form1.label_S.Text=(i++).ToString();
}
}
}

...全文
589 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
IBM___ 2005-11-24
  • 打赏
  • 举报
回复
事实上timer1的tick事件并没有被执行,更不更新的无所谓,而且后面已经不用Label显示数据来证明Class1的timer在工作了,改用播放声音的方法,如果听到声音就说明timer在工作,但仍然听不到声音
shisan_1 2005-11-24
  • 打赏
  • 举报
回复
Form1.label_S.Text=(i++).ToString();
Form1.Update();

界面没更新,更新一下,值就变了。
ljasmine 2005-11-23
  • 打赏
  • 举报
回复
用button2有声音吗
IBM___ 2005-11-23
  • 打赏
  • 举报
回复
有谁知道是怎么回事???
IBM___ 2005-11-23
  • 打赏
  • 举报
回复
现在我已经不用Label显示数据来证明Class1的timer在工作了,我用播放声音的方法,如果听到声音就说明timer在工作,但跟本听不到声音啊
zhy0101 2005-11-23
  • 打赏
  • 举报
回复
不要在创建控件以外的线程操作控件,.Net 2.0已经把这个作为异常了。可以使用Control的Invoke方法,将操作放到UI线程上。

private void Form1_Load(object sender, System.EventArgs e)
{
System.Threading.Thread tNew = new System.Threading.Thread (new System.Threading.ThreadStart(this.Test));
tNew.Start();
}

delegate void SetVisibleDelegate();

private void SetVisible()
{
this.button1.Visible = true;
}

private void Test()
{
this.Invoke(new SetVisibleDelegate(SetVisible));
}
IBM___ 2005-11-23
  • 打赏
  • 举报
回复
ljasmine:你的方法可以正常运行。但我仍想不明白,我在Class1的timer_tick函数里加了一个播放一个小声音的语句,不涉及访问Form1的控件的属性,用以前我的方法启动线程,仍然不成功,没听到声音,也就是说Class1的timer_tick函数里的语句跟本就没有执行,这是为什么????
seaangel 2005-11-23
  • 打赏
  • 举报
回复
关注
ljasmine 2005-11-23
  • 打赏
  • 举报
回复
netsd(极品非车)说的对
具体如下
定义一个委托
delegate void UpdateSumDisplay();
然后修改button1_Click的代码为如下
label1.BeginInvoke(new UpdateSumDisplay(TheadS));

IBM___ 2005-11-23
  • 打赏
  • 举报
回复
是不是因为生成的Class1对象被清理掉了。
tinghuyang 2005-11-23
  • 打赏
  • 举报
回复
学习
IBM___ 2005-11-23
  • 打赏
  • 举报
回复
netsd:是难以改变UI界面的,在需要用Invoke方法而你并没有时,编译器会提示错误的。而现在这个程序并未提示错误。
IBM___ 2005-11-23
  • 打赏
  • 举报
回复
levinknigh:能不能说详细点啊?谢谢
levinknight 2005-11-23
  • 打赏
  • 举报
回复
用DELEGAET进行异步调用
netsd 2005-11-23
  • 打赏
  • 举报
回复
子线程一般是难以改变UI界面的,可用控件的Invoke方法,你可以参考一下下面这个例子
// 为清楚起见,省略了一些成员
public void btnAdd_OnClick(object sender, EventArgs e)
{
// 在创建 _txtSum 的线程上执行 UpdateSumDisplay
_txtSum.Invoke(new EventHandler(UpdateSumDisplay));
}
public void UpdateSumDisplay(object sender, EventArgs e)
{
_txtSum.Text = _sum.ToString();
}
wormwormwormworm 2005-11-23
  • 打赏
  • 举报
回复
up
IBM___ 2005-11-23
  • 打赏
  • 举报
回复
up
IBM___ 2005-11-23
  • 打赏
  • 举报
回复
嗯,这个就不知道了。不过我另外一个程序里有同样的问题,我没用timer,只用了事件,是不是事件不能用。
ljasmine 2005-11-23
  • 打赏
  • 举报
回复
我的理解是:是不是必须在窗体所在的主线程中运行
IBM___ 2005-11-23
  • 打赏
  • 举报
回复
MSDN上说的Windows 窗体应用程序应该是和控制台应用程序等对立的,上面那个程序本是就是Windows 窗体应用程序了。所以我觉得问题应该不会出在timer身上。
加载更多回复(6)

110,570

社区成员

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

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

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