当button1仍在工作时,如何按第二个按钮 [英] How can I press 2nd button when button1 is still working

查看:98
本文介绍了当button1仍在工作时,如何按第二个按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 private void button1_Click(object sender,EventArgs e)
{
for(int i = 0; i< 1000000; i ++)
{
label1.Text = i.ToString();
}

}

private void button2_Click(object sender,EventArgs e)
{
label1.Text = 0.ToString() ;
}< / pre

按下按钮1后,我正在增加,按钮2被锁定,直到我完成。
我怎么能随时按下button2?

我尝试过:

< pre> private void button1_Click(object sender,EventArgs e)
{
Thread th1 = new Thread(Increment);
th1.Start();

}
private void Increment()
{
for(int i = 0; i< 10000; i ++)
{
label1.Text = i.ToString();
}
}

private void button2_Click(object sender,EventArgs e)
{
reset();
}
private void reset()
{
label1.Text = 0.ToString();
}

解决方案

你不能。您将UI线程绑定在button1处理程序中完成所有工作。在该方法返回之前,UI无法重新绘制(这就是为什么标签在更改时不显示值)并且无法响应鼠标和键事件。



您必须将按钮处理程序中长时间运行的代码移动到后台线程。那个问题是线程无法直接更新标签控件本身。您必须在UI线程上调用方法并传递您希望标签显示的值。然后,您调用的此方法将使用新值更新标签。



请阅读:如何:对Windows窗体控件进行线程安全调用Microsoft Docs [ ^ ]


你好,

这个问题对我很有意思我正在学习C#,这是我的解决方案:



MainForm.cs

使用系统;使用System.Drawing 
;
使用System.Threading;
使用System.Windows.Forms;

名称空间Buttons_and_Threading
{
///< summary>
/// MainForm的描述。
///下面的程序代码需要两个按钮和一个标签
///初始按钮前颜色应设置为绿色
///它需要.net framework 4.0才能完美运行
///< / summary>
public partial class MainForm:Form
{
public MainForm()
{
//
// InitializeComponent()call
/ /是Windows窗体设计器支持所必需的。
//
InitializeComponent();
}

#region-并行处理方法和变量 -

线程并行;
int i;

protected delegate void Refresh_Data(string Text);

void Button_1()
{
for(i = 0; i< 1000000; i ++)
{

if(label1 .InvokeRequired)
{
Refresh_Data refresh = Refresh_Label_1_Text;
Invoke(refresh,i.ToString());
}

}
}

void Initialize_and_Start_New_Thread()
{
Parallel = new Thread(Button_1);
Parallel.Start();
}

void Stop_Thread()
{
Parallel.Abort();
while(Parallel.ThreadState!= ThreadState.Aborted)
{

}
}

void Refresh_Label_1_Text(string Text)
{
label1.Text = Text;
}

void MainFormFormClosing(对象发送者,
System.Windows.Forms.FormClosingEventArgs e)
{
//
//之前关闭程序检查并行线程是
//仍在运行并停止它
//

if(Parallel.ThreadState!= ThreadState.Aborted)
{
Parallel.Abort();
while(Parallel.ThreadState!= ThreadState.Aborted)
{
//
//在并行线程停止之前什么都不做
//
}
}
}
#endregion

void Button1Click(对象发送者,EventArgs e)
{
if(button1.ForeColor == Color) .ForestGreen)
{
//
//将按钮文字collor更改为红色,
//启动新的并行线程
//
button1.ForeColor = Color.Red;
Initialize_and_Start_New_Thread();
}
其他
{
//
//停止并行线程和
//将按钮文字collor更改为绿色
//
Stop_Thread();
button1.ForeColor = Color.ForestGreen;
}
}

void Button2Click(对象发送者,EventArgs e)
{
//
//将计数器重置为零和
//更新标签1文本
//
i = 0;
if(label1.InvokeRequired)
{
Refresh_Data refresh = Refresh_Label_1_Text;
Invoke(refresh,i.ToString());
}

else
Refresh_Label_1_Text(i.ToString());
}
}
}







Main .Form.Designer.cs

命名空间Buttons_and_Threading 
{
partial class MainForm
{
/// <总结>
///用于跟踪非可视组件的Designer变量。
///< / summary>
private System.ComponentModel.IContainer components = null;

///< summary>
///处理表单使用的资源。
///< / summary>
///< param name =disposing>如果应该处理托管资源,则为true;否则,假。< / param>
protected override void Dispose(bool disposing)
{
if(disposing){
if(components!= null){
components.Dispose();
}
}
base.Dispose(disposing);
}

///< summary>
/// Windows窗体设计器支持需要此方法。
///不要更改源代码编辑器中的方法内容。如果手动更改,窗体设计器可能
///无法加载此方法。
///< / summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// button1
//
this.button1.ForeColor = System.Drawing.Color.ForestGreen;
this.button1.Location = new System.Drawing.Point(14,18);
this.button1.Margin = new System.Windows.Forms.Padding(5,4,5,4);
this.button1.Name =button1;
this.button1.Size = new System.Drawing.Size(264,38);
this.button1.TabIndex = 0;
this.button1.Text =按钮1;
this.button1.UseVisualStyleBackColor = false;
this.button1.Click + = new System.EventHandler(this.Button1Click);
//
// button2
//
this.button2.ForeColor = System.Drawing.Color.ForestGreen;
this.button2.Location = new System.Drawing.Point(14,64);
this.button2.Margin = new System.Windows.Forms.Padding(5,4,5,4);
this.button2.Name =button2;
this.button2.Size = new System.Drawing.Size(264,38);
this.button2.TabIndex = 1;
this.button2.Text =按钮2;
this.button2.UseVisualStyleBackColor = false;
this.button2.Click + = new System.EventHandler(this.Button2Click);
//
// label1
//
this.label1.Location = new System.Drawing.Point(20,127);
this.label1.Margin = new System.Windows.Forms.Padding(5,0,5,0);
this.label1.Name =label1;
this.label1.Size = new System.Drawing.Size(158,29);
this.label1.TabIndex = 2;
this.label1.Text =Label 1;
//
// MainForm
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(292,171);
this.Controls.Add(this.label1);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Font = new System.Drawing.Font(Arial,12F,System.Drawing.FontStyle.Bold,System.Drawing.GraphicsUnit.Point,((byte)(204)));
this.Margin = new System.Windows.Forms.Padding(5,4,5,4);
this.MaximizeBox = false;
this.MaximumSize = new System.Drawing.Size(300,200);
this.MinimizeBox = false;
this.Name =MainForm;
this.Text =按钮和线程;
this.FormClosing + = new System.Windows.Forms.FormClosingEventHandler(this.MainFormFormClosing);
this.ResumeLayout(false);
}
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button1;
}
}





尝试学习如何使用Delegates,codeproject有很多关于该主题的文章。



一切顺利,
$ b $bŽeljkoPerić


是的,你需要线程,最简单使用它的方法是使用'BackgroundWorker。 CodeProject是你的朋友:[ ^ ],[ ^ ],[ ^

       private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 1000000; i++)
            {
                label1.Text = i.ToString();
            }
           
        }

        private void button2_Click(object sender, EventArgs e)
        {
            label1.Text = 0.ToString();
        }</pre

After i press button1, i is increasing and button2 is Locked until i is finished.
how can i press button2 at anytime?

What I have tried:

<pre>      private void button1_Click(object sender, EventArgs e)
        {
            Thread th1 = new Thread(Increment);
            th1.Start();
           
        }
        private void Increment()
        {
            for (int i = 0; i < 10000; i++)
            {
                label1.Text = i.ToString();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            reset();
        }
        private void reset()
        {
            label1.Text = 0.ToString();
        }

解决方案

You can't. You have the UI thread tied up doing all of the work in the button1 handler. Until that method returns, the UI cannot repaint itself (that's why your label doesn't show a value when you change it) and cannot respond to mouse and key events.

You have to move the long running code in the button handler to a background thread. That catch is that thread will NOT be able to directly update the label control itself. You have to Invoke a method on the UI thread and pass the value you want the label to show. This method you invoke will then update the label with the new value.

Read this:
How to: Make Thread-Safe Calls to Windows Forms Controls | Microsoft Docs[^]


Hello,
this problem was interesting to me when I was learning C#, and here is my solution :

MainForm.cs

using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

namespace Buttons_and_Threading
{
	/// <summary>
	/// Description of MainForm.
	/// Program code below needs two buttons and one label
	/// Initial buttons fore color should be set to green
	/// it needs .net framework 4.0 to run perfectly
	/// </summary>
	public partial class MainForm : Form
	{
		public MainForm()
		{
			//
			// The InitializeComponent() call 
			// is required for Windows Forms designer support.
			//
			InitializeComponent();
		}
		
		#region-   Parallel process methods and variables   -
		
		Thread Parallel;
		int i;
		
		protected delegate void Refresh_Data(string Text);
		
		void Button_1()
		{
			for (i = 0; i < 1000000; i++)
			{
				
				if(label1.InvokeRequired)
				{
					Refresh_Data refresh = Refresh_Label_1_Text;
					Invoke(refresh,i.ToString());
				}
				
			}
		}
		
		void Initialize_and_Start_New_Thread()
		{
			Parallel = new Thread(Button_1);
			Parallel.Start();
		}
		
		void Stop_Thread()
		{
			Parallel.Abort();
			while(Parallel.ThreadState != ThreadState.Aborted)
			{
				
			}
		}
		
		void Refresh_Label_1_Text(string Text)
		{
			label1.Text = Text;
		}
		
		void MainFormFormClosing(object sender, 
		                         System.Windows.Forms.FormClosingEventArgs e)
		{
			//
			// Before closing program check does parallel thread is
			// still running and stop it
			//
			
			if(Parallel.ThreadState != ThreadState.Aborted)
			{
				Parallel.Abort();
				while(Parallel.ThreadState != ThreadState.Aborted)
				{
					//
					// do nothing until parallel thread is stopped
					//
				}
			}
		}
		#endregion
		
		void Button1Click(object sender, EventArgs e)
		{
			if(button1.ForeColor == Color.ForestGreen)
			{
				//
				// change button text collor to red and 
				// start new parallel thread
				//
				button1.ForeColor = Color.Red;
				Initialize_and_Start_New_Thread();
			}
			else
			{
				//
				// Stop parallel thread and
				// change button text collor to green
				//
				Stop_Thread();
				button1.ForeColor = Color.ForestGreen;
			}
		}
		
		void Button2Click(object sender, EventArgs e)
		{
			//
			// reset counter to zero and
			// update label 1 text
			//
			i=0;
			if(label1.InvokeRequired)
			{
				Refresh_Data refresh = Refresh_Label_1_Text;
				Invoke(refresh,i.ToString());
			}
			
			else
				Refresh_Label_1_Text(i.ToString());
		}
	}
}




Main.Form.Designer.cs

namespace Buttons_and_Threading
{
	partial class MainForm
	{
		/// <summary>
		/// Designer variable used to keep track of non-visual components.
		/// </summary>
		private System.ComponentModel.IContainer components = null;
		
		/// <summary>
		/// Disposes resources used by the form.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing) {
				if (components != null) {
					components.Dispose();
				}
			}
			base.Dispose(disposing);
		}
		
		/// <summary>
		/// This method is required for Windows Forms designer support.
		/// Do not change the method contents inside the source code editor. The Forms designer might
		/// not be able to load this method if it was changed manually.
		/// </summary>
		private void InitializeComponent()
		{
			this.button1 = new System.Windows.Forms.Button();
			this.button2 = new System.Windows.Forms.Button();
			this.label1 = new System.Windows.Forms.Label();
			this.SuspendLayout();
			// 
			// button1
			// 
			this.button1.ForeColor = System.Drawing.Color.ForestGreen;
			this.button1.Location = new System.Drawing.Point(14, 18);
			this.button1.Margin = new System.Windows.Forms.Padding(5, 4, 5, 4);
			this.button1.Name = "button1";
			this.button1.Size = new System.Drawing.Size(264, 38);
			this.button1.TabIndex = 0;
			this.button1.Text = "Button 1";
			this.button1.UseVisualStyleBackColor = false;
			this.button1.Click += new System.EventHandler(this.Button1Click);
			// 
			// button2
			// 
			this.button2.ForeColor = System.Drawing.Color.ForestGreen;
			this.button2.Location = new System.Drawing.Point(14, 64);
			this.button2.Margin = new System.Windows.Forms.Padding(5, 4, 5, 4);
			this.button2.Name = "button2";
			this.button2.Size = new System.Drawing.Size(264, 38);
			this.button2.TabIndex = 1;
			this.button2.Text = "Button 2";
			this.button2.UseVisualStyleBackColor = false;
			this.button2.Click += new System.EventHandler(this.Button2Click);
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(20, 127);
			this.label1.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(158, 29);
			this.label1.TabIndex = 2;
			this.label1.Text = "Label 1";
			// 
			// MainForm
			// 
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
			this.ClientSize = new System.Drawing.Size(292, 171);
			this.Controls.Add(this.label1);
			this.Controls.Add(this.button2);
			this.Controls.Add(this.button1);
			this.Font = new System.Drawing.Font("Arial", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
			this.Margin = new System.Windows.Forms.Padding(5, 4, 5, 4);
			this.MaximizeBox = false;
			this.MaximumSize = new System.Drawing.Size(300, 200);
			this.MinimizeBox = false;
			this.Name = "MainForm";
			this.Text = "Buttons and Threading";
			this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainFormFormClosing);
			this.ResumeLayout(false);
		}
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Button button2;
		private System.Windows.Forms.Button button1;
	}
}



Try to learn how to work with Delegates, codeproject has many articles on that subject.

All the best,
Željko Perić


Yes, you need threading, and the simplest way to use it is with the 'BackgroundWorker. CodeProject is your friend: [^], [^], [^]


这篇关于当button1仍在工作时,如何按第二个按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆