多线程程序中,显示子窗体上按钮单击事件处理无效?

glen 2003-01-09 05:22:57
/*

下面包括两个窗体的代码:Form1.cs,FormProcess.cs
在Form1.cs中按下Starting按钮,执行主任务1000000000条循环,并启动另一线程
在DisplayNumbers()函数中及时更新进度放在FormProcess中显示,此时FormProcess窗体的取消按钮事件无效,请问如何在执行此大任务期间,用户按取消按钮后,处理事件生效,请高手指点,谢谢!
*/
//Form1.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
namespace ThreadWinForm
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;

public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
CurrValue=0;
}
private int CurrValue;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(16, 16);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "Starting";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(16, 48);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ReadOnly = true;
this.textBox1.Size = new System.Drawing.Size(360, 144);
this.textBox1.TabIndex = 1;
this.textBox1.Text = "";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(400, 245);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.textBox1,
this.button1});
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// 应用程序的主入口点。
/// </summary>
static int Interval;
static Form1 myWin; //实例
static void Main()
{
Interval=1000000000;
Thread ThisThread=Thread.CurrentThread;
ThisThread.Name="Main Thread";
DisplayNumbers();
}
static void DisplayNumbers()
{
Thread ThisThread=Thread.CurrentThread;
string Name=ThisThread.Name;
if(Name=="Main Thread")//主窗体
{
myWin=new Form1();
Application.Run(myWin);
}
else
{
//并行2
FormProcess glf=new FormProcess();//进度条
glf.SetMax(Interval);
glf.Show();
DateTime a=DateTime.Now;//任务开始时间
while(myWin.CurrValue<Interval-1)
{
DateTime b=DateTime.Now;//当前时间
TimeSpan c=b-a;
lock(myWin)//lock
{
glf.SetCurr(myWin.CurrValue,c.Ticks);
glf.ControlRefresh();
}
//unlock
//Thread.Sleep(),增加一倍的时间
//Thread.Sleep(1);
}
glf.Dispose();
}
}
static void StartMethod()
{
DisplayNumbers();
}
private void button1_Click(object sender, System.EventArgs e)
{
ThreadStart WorkerStart=new ThreadStart(StartMethod);
Thread WorkerThread=new Thread(WorkerStart);
WorkerThread.Name="Worker";
WorkerThread.Start();
//并行1(主任务开始)
for(int i=0;i<Interval;i++)
{
CurrValue=i;
}
//并行1(主任务结束)
WorkerThread.Abort();
}
}
}
//FormProcess.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace ThreadWinForm
{
/// <summary>
/// FormProcess 的摘要说明。
/// </summary>
public class FormProcess : System.Windows.Forms.Form
{
private System.Windows.Forms.ProgressBar pbLoad;
private System.Windows.Forms.Label labelStat;
private System.Windows.Forms.Button buttonCancel;
private System.ComponentModel.IContainer components;

public FormProcess()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//


}

/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.pbLoad = new System.Windows.Forms.ProgressBar();
this.labelStat = new System.Windows.Forms.Label();
this.buttonCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// pbLoad
//
this.pbLoad.Location = new System.Drawing.Point(12, 26);
this.pbLoad.Name = "pbLoad";
this.pbLoad.Size = new System.Drawing.Size(204, 16);
this.pbLoad.TabIndex = 0;
//
// labelStat
//
this.labelStat.AutoSize = true;
this.labelStat.Location = new System.Drawing.Point(16, 48);
this.labelStat.Name = "labelStat";
this.labelStat.Size = new System.Drawing.Size(42, 14);
this.labelStat.TabIndex = 1;
this.labelStat.Text = "label1";
//
// buttonCancel
//
this.buttonCancel.Location = new System.Drawing.Point(224, 24);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.TabIndex = 2;
this.buttonCancel.Text = "取消(&C)";
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
//
// FormProcess
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(312, 85);
this.ControlBox = false;
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.buttonCancel,
this.labelStat,
this.pbLoad});
this.Name = "FormProcess";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "正在计算 , 请稍候...";
this.Load += new System.EventHandler(this.FormProcess_Load);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.FormProcess_Paint);
this.ResumeLayout(false);

}
#endregion

public void SetMax(int TheMax)
{
pbLoad.Maximum=TheMax;
pbLoad.Step=TheMax/10;
}
public void SetCurr(int TheCurr,long nTime)
{
//TheCurr,当前进度条的值
//nTime,时间片
pbLoad.Value=TheCurr;
labelStat.Text="第"+TheCurr.ToString()+"条..."+(nTime/10000).ToString()+"Ticks/10000";
}
public void ControlRefresh()
{
this.labelStat.Refresh();
this.buttonCancel.Refresh();
}
private void FormProcess_Load(object sender, System.EventArgs e)
{

}

private void button1_Click(object sender, System.EventArgs e)
{

}

private void buttonCancel_Click(object sender, System.EventArgs e)
{
Close();
}

private void FormProcess_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
}



}
}

...全文
47 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
glen 2003-01-10
  • 打赏
  • 举报
回复
通过Application.DoEvents();问题已解决!!!
等个人网站做好后,将本程序上传,供大家下载,谢谢!
/*
* 设计思想:
* 实现类似Windows资源管理器复制文件的效果,当复制文件开始时,弹出一个对话框,显示复制进度,用户随时可
* 按下取消按钮来中止复制任务。
* 在主线程中,有个变量IsBreak,用户单击[取消]按钮时相应设置这个变量为true
* 在子线程中,也有个变量IsBreak,用户单击[取消]按钮时设置这个变量为true
* 注意一个是IsBreak,一个是glf.IsBreak是不同的!!!
* 程序的执行途径有两条:1,任务完成;2,用户中止
* 1.任务完成后,主线程序通过WorkerThread.Abort()方法结束子线程。
* 2.用户中止时,子线程序通IsBreak变量设置为ture,来退出循环。
*/
glen 2003-01-10
  • 打赏
  • 举报
回复
DoEvents(),是哪个对象的方法?
Hobbytp 2003-01-09
  • 打赏
  • 举报
回复
呵呵,就像楼上说的用DoEvents,会用vb6的都认识它啦,能使你在百忙中抽出一点空来解决其他在等待的进程。
七里十二斋 2003-01-09
  • 打赏
  • 举报
回复
DoEvents()
faku 2003-01-09
  • 打赏
  • 举报
回复
分解主任务成n条小任务,每条小任务时间足够短,在两条短任务之间
利用回调或事件的方式检查是否用户点击了取消按钮

111,119

社区成员

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

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

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