定时器在单独的线程

时间:2012-02-11 19:46:14

标签: c# timer

我想在一个单独的线程中创建一个计时器,但我不知道该怎么做。 单击按钮后,计时器应停止。

下面我有一个主要有效的例子,但是当循环执行时它有时会停止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");
        }
    }
}

2 个答案:

答案 0 :(得分:0)

在您的代码中,似乎定时器与打印时间之间没有任何关联。 您需要注意,因为无法从不是主要线程的另一个线程更改GUI元素。 为此,您需要在WinForms中使用Invoke

if (control.InvokeRequired)
  {
    control.Invoke(new SetControlPropertyThreadSafeDelegate(SetControlPropertyThreadSafe), new object[] { control, propertyName, propertyValue });
  }
  else
  {
    control.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, control, new object[] { propertyValue });
  }
WPF / SL中的

或调度员 - http://www.switchonthecode.com/tutorials/working-with-the-wpf-dispatcher

为了使用另一个线程,你有一些选择:

  1. Threadpool(在.Net 4上) - http://msdn.microsoft.com/en-us/library/3dasc8as(v=vs.80).aspx
  2. 主题类 - http://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx
  3. BackgroundWorker类 - http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
  4. 如果您不知道如何使用这些选项,第三个选项是最简单的

答案 1 :(得分:0)

.Net中的树计时器会查看以下文章并选择正确的timer,看起来您需要来自System.Threading的计时器,而不是来自System.Windows.Forms