问题描述
基本上,我的表单中有多个按钮,我希望它在按钮被按下时在 button.Text 中显示一个秒表.(按钮被修改为切换按钮.)并在按钮关闭时停止并重置计时器.看起来很简单,但因为我有多个按钮可以按任何顺序按下,而且我对线程一无所知,这似乎比我想象的要困难得多.
Basically, I've got multiple button in my Form, and I want for it show a Stopwatch in the button.Text when the button is pressed. (Button is modified to be a toggle button.) and to stop and reset the timmer when the button is toggled off. Simple enough it seemed but because I have multiple buttons that could be pressed in any order, and I don't know anything about threading, this seems to be much more difficult that I presumed.
我最初的意图是拥有一个每秒持续运行的函数,并且仅当使用以下代码按下按钮时才与 interager 交互:
My origional intent was to have a function that constantly runs every second and interates a interager only if the button is pressed using this code:
public void Jogger()//purpose is to step up time[0] every second only when a button is on.
{
while (true)
{
for (int i = 0; i < 16; i++)
{
if (btnstat[i])
time[i]++;
}
Thread.Sleep(1000);
}
}
问题是,我不知道线程,所以当我调用函数时,它卡住了这样做,而且只做这个.
Problem is, I don't know threading so when I call the function, its stuck doing this and only this.
无论哪种方式,一旦被调用,我所做的就是调用我的更新函数来更新所有按钮,包括显示时间 [0] 的 button.Text;(围绕按钮构建的数组)
Either way, once this is called, all i do us call my update function that updates all the buttons including the button.Text which displays the time[0]; (array built around buttons)
他们是否有更好的方法来做到这一点,不会导致过多的 CPU 使用和/或只是有效?
Is their a better way of doing this that doesn't cause so much CPU use and/or simply works?
感谢大家的帮助!-约翰·艾维
Thanks for all the help!-John Ivey
推荐答案
Application.DoEvents()
为简单起见放在 loop 内..但建议开始精益 threading
.您将学习如何启动线程以及如何进行跨线程安全调用下一个简单的方法是使用 backgroundworker
.看看这个 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Application.DoEvents()
for simplicity put inside loop . . but it is advisable to start to lean threading
. you will just learn how to start thread and how make cross thread safe callNext simple will be to use backgroundworker
. look this http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
好的,这里也是你想要的线程解决方案.测试过.作为停止变量,我使用了标签.但是你可以继承按钮来使状态按钮变得更清晰.下面的代码将每个按钮使用一个线程.所以你应该在一个线程中使它成为更好的解决方案.您可以修改此代码以在一个线程内进行所有检查.为此,您启动线程一次可以委托为每个按钮附加动态计数功能,或者您可以在之前传递按钮.一个词有不止一种方法可以做到.祝你好运
ok here is thread solution also as you wanted . Tested too . as a stop variable i used Tag. But u can inherit button to make state button.it be more clear way . And below code will use one thread per button . So u should make it in one thread to make it better solution . You can modify this code to do all checkings inside one thread . For this you start thread once can make delegate for attaching dinamically count function for each button or you can pass buttons before . With one word there are more than one way to do it. Good luck
this.button1.Click += new System.EventHandler(this.button_Click);
this.button2.Click += new System.EventHandler(this.button_Click);
...and so on
private void button_Click(object sender, EventArgs e)
{
Thread x= new Thread(new ParameterizedThreadStart(Jogger2));
x.Start(sender);
}
private void button_Click(object sender, EventArgs e)
{
Button mybtn=sender as Button;
if((string)mybtn.Tag=="start"){
mybtn.Tag ="";
return;
}
mybtn.Tag = "start";
Thread x= new Thread(new ParameterizedThreadStart(Jogger2));
x.Start(sender);
}
private bool setResult(object obj,string text)
{
if (this.textBox1.InvokeRequired)
{
Func<Button,string, bool > d = new Func<Button,string,bool >(setResult);
return (bool)this.Invoke(d,obj,text);
}
else
{
Button btn=obj as Button;
if (btn != null)
{
btn.Text = text;
if ((string)btn.Tag !="start") return false;
}
return true;
}
}
private void Jogger2(object mybtn)
{
int ii = 0;
while (true)
{
Thread.Sleep(1000);
//replace with your code
ii += 1;
if (!setResult(mybtn, ii.ToString())) break;
}
}
这篇关于秒表在 C# 中更改按钮文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!