单独线程中的计时器
我想在单独的线程中创建一个计时器,但我不知道该怎么做。 单击一个按钮后计时器应停止。
下面我有一个大部分有效的示例,但在执行循环时有时会停止 1-2 秒。所以我想我必须把它放在一个单独的线程中?这是我尝试过的:
private void buttonStop_Click(object sender, EventArgs e)
{
timer1.Stop();
}
public void TimeThread()
{
th = new Thread(new ThreadStart(Timer));
th.Start();
}
public void Timer()
{
var delta = DateTime.Now - startTime;
textBoxSeconds.Text = delta.Seconds.ToString("n0");
textBoxMinutes.Text = Math.Floor(delta.TotalMinutes).ToString("n0");
}
编辑: 这是我拥有的所有代码,但仍然不确定如何将计时器放在单独的线程中。
namespace Imgur
{
public partial class Form1 : Form
{
bool flag = true;
int downloadedNumber = 0;
private DateTime startTime;
public Form1()
{
InitializeComponent();
}
public void buttonStart_Click(object sender, EventArgs e)
{
buttonStart.Enabled = false;
buttonStop.Enabled = true;
if (!flag)
{
flag = true;
}
startTime = DateTime.Now;
timer1.Start();
for (int i=0;i<100000 && flag;i++)
{
WebClient webClient = new WebClient();
string pic1 = rnd_str(5);
string pic2 = ".jpg";
string picture = pic1 + pic2;
//********** GETTING SIZE OF IMAGE ***********
Size sz = GetSize("http://i.imgur.com/" + picture);
string imageSize = (sz.Width.ToString() + " " + sz.Height.ToString()); ;
//********************************************
if(imageSize != "161 81")
{
webClient.DownloadFile("http://i.imgur.com/" + picture, @"e:\test\" + picture);
richTextBox1.Text += String.Format("Downloaded picture: {0}\r\n", picture);
downloadedNumber++;
textBoxDownloadedNumber.Text = string.Format("{0}", downloadedNumber);
}
webClient.Dispose();
Application.DoEvents();
if (i == 999995)
{
flag = false;
}
}
richTextBox1.Text += "End Dowloaded Session \n";
buttonStart.Enabled = true;
buttonStop.Enabled = false;
timer1.Stop();
}
public static Size GetSize(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.Accept = "image/gif";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream s = response.GetResponseStream();
Bitmap bmp = new Bitmap(s);
Size sz = new Size(bmp.Width, bmp.Height);
return sz;
}
public static string rnd_str(int liczba_liter)
{
Random r = new Random();
int char_type;
string return_string = "";
int i =0;
for (i = 0; i < liczba_liter; i++)
{
if (r.Next(1, 3) == 1)
{
char_type = r.Next(1, 4);
switch (char_type)
{
case 1:
return_string += (char)r.Next(48, 58); // convertion int -> ASCII character; 48-57 are ASCII digits
break;
case 2:
return_string += (char)r.Next(97, 123); // convertion int -> ASCII character; as above but small letters
break;
case 3:
return_string += (char)r.Next(65, 91); // as above; large letters
break;
default:
i -= 1;
break;//do not add any letter if no type is allowed
}
}
else
{
i -= 1;
return_string += "";
}
}
return return_string;
}
private void buttonStop_Click(object sender, EventArgs e)
{
flag = false;
buttonStart.Enabled = true;
timer1.Stop();
}
public void timer1_Tick(object sender, EventArgs e)
{
var delta = DateTime.Now - startTime;
textBoxSeconds.Text = delta.Seconds.ToString("n0");
textBoxMinutes.Text = Math.Floor(delta.TotalMinutes).ToString("n0");
}
}
}
I want to create a timer in a separate thread, but I'm not sure how to do it.
The timer should stop after clicking button a button.
Below I have an example that mostly works but it stops sometimes for 1-2 seconds when the loop is executing. So I guess I have to put it in a separate thread? This is what I've tried:
private void buttonStop_Click(object sender, EventArgs e)
{
timer1.Stop();
}
public void TimeThread()
{
th = new Thread(new ThreadStart(Timer));
th.Start();
}
public void Timer()
{
var delta = DateTime.Now - startTime;
textBoxSeconds.Text = delta.Seconds.ToString("n0");
textBoxMinutes.Text = Math.Floor(delta.TotalMinutes).ToString("n0");
}
EDIT:
So here is all the code that I have, still not exactly sure how to put the timer in separate thread.
namespace Imgur
{
public partial class Form1 : Form
{
bool flag = true;
int downloadedNumber = 0;
private DateTime startTime;
public Form1()
{
InitializeComponent();
}
public void buttonStart_Click(object sender, EventArgs e)
{
buttonStart.Enabled = false;
buttonStop.Enabled = true;
if (!flag)
{
flag = true;
}
startTime = DateTime.Now;
timer1.Start();
for (int i=0;i<100000 && flag;i++)
{
WebClient webClient = new WebClient();
string pic1 = rnd_str(5);
string pic2 = ".jpg";
string picture = pic1 + pic2;
//********** GETTING SIZE OF IMAGE ***********
Size sz = GetSize("http://i.imgur.com/" + picture);
string imageSize = (sz.Width.ToString() + " " + sz.Height.ToString()); ;
//********************************************
if(imageSize != "161 81")
{
webClient.DownloadFile("http://i.imgur.com/" + picture, @"e:\test\" + picture);
richTextBox1.Text += String.Format("Downloaded picture: {0}\r\n", picture);
downloadedNumber++;
textBoxDownloadedNumber.Text = string.Format("{0}", downloadedNumber);
}
webClient.Dispose();
Application.DoEvents();
if (i == 999995)
{
flag = false;
}
}
richTextBox1.Text += "End Dowloaded Session \n";
buttonStart.Enabled = true;
buttonStop.Enabled = false;
timer1.Stop();
}
public static Size GetSize(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.Accept = "image/gif";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream s = response.GetResponseStream();
Bitmap bmp = new Bitmap(s);
Size sz = new Size(bmp.Width, bmp.Height);
return sz;
}
public static string rnd_str(int liczba_liter)
{
Random r = new Random();
int char_type;
string return_string = "";
int i =0;
for (i = 0; i < liczba_liter; i++)
{
if (r.Next(1, 3) == 1)
{
char_type = r.Next(1, 4);
switch (char_type)
{
case 1:
return_string += (char)r.Next(48, 58); // convertion int -> ASCII character; 48-57 are ASCII digits
break;
case 2:
return_string += (char)r.Next(97, 123); // convertion int -> ASCII character; as above but small letters
break;
case 3:
return_string += (char)r.Next(65, 91); // as above; large letters
break;
default:
i -= 1;
break;//do not add any letter if no type is allowed
}
}
else
{
i -= 1;
return_string += "";
}
}
return return_string;
}
private void buttonStop_Click(object sender, EventArgs e)
{
flag = false;
buttonStart.Enabled = true;
timer1.Stop();
}
public void timer1_Tick(object sender, EventArgs e)
{
var delta = DateTime.Now - startTime;
textBoxSeconds.Text = delta.Seconds.ToString("n0");
textBoxMinutes.Text = Math.Floor(delta.TotalMinutes).ToString("n0");
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您的代码中,计时器和经过的时间的打印之间似乎没有任何联系。
您需要注意,因为不可能从非主线程的另一个线程更改 GUI 元素。
为此,您需要在 WinForms 中使用 Invoke
或在 WPF/SL 中使用调度程序 - http://www.switchonthecode.com/tutorials/working-with-the-wpf-dispatcher
为了使用另一个线程,你有一些选择:
如果您不知道如何使用 theards,第三个选项是最简单的
In your code it seems there is no connection between the timer and the print of the time passed.
You need to pay attention because it isn't possible to change GUI elements from another thread that isn't the main one.
To do this you need to use Invoke in WinForms
or dispatcher in WPF/SL - http://www.switchonthecode.com/tutorials/working-with-the-wpf-dispatcher
In order to use another thread and you have some options:
The 3rd option is the easiest if you don't know how to work with theards
.Net 中有树计时器,请查看以下文章并选择正确的 计时器 看起来您需要来自
System.Threading
的计时器,而不是来自System.Windows.Forms
的计时器。There're tree Timers in .Net take a look at the following article and select correct timer looks like you need timer from
System.Threading
, not fromSystem.Windows.Forms
.